tunnelx-20140102.orig/0000755000000000000000000000000012261237231011266 5ustar tunnelx-20140102.orig/README.txt0000644000000000000000000000441211762432750012775 0ustar Files locations --------------- (Julian Todd, 2009-06-21) The scripts b(.bat) and j(.bat) compile and package a jar file for you, r runs it with appropriate command line settings. Vary these according to which compiler version you have. The default symbols directory is either ~/.tunnelx/symbols/ or /usr/share/tunnelx/symbols/ or tunnelx[current directory]/symbols/ [particularly in Windows]. The tmp file used for calling cavern is ~/.tunnelx/tmp/tunnel_tmp_all.svx or /tmp/tunnel_tmp_all.svx or tunnelx[current directory]/tmp/tunnel_tmp_all.svx The .jar file version additionally contains its own symbols directory so it can run self-contained like an executable. Settings can be found in TN.java and FileAbstraction.java, which include setting the username, project name and password (in the case of uploading to troggle capability). Compiling and running Tunnel ---------------------------- (David Loeffler, Sunday 2006-01-22) To compile Tunnel on a Windows system, grab a DOS window, change to the Tunnel directory and run the following command: "C:\Program Files\Java\jdk1.5.0_06\bin\javac" -d . -source 1.5 src\*.java You'll need to have the Java Development Kit installed to do this; it can be downloaded from java.sun.com. You may need to edit the path to the Java compiler, depending on where the installer puts it. The batch file "b.bat" is provided in case you need to do this frequently; but this will only apply to people doing Tunnel development, who can probably work this out for themselves. For other operating systems, something similar should work; just run the Java compiler in whatever way you normally would on your system. (If anyone feels like trying this out on a Mac and checking that it works, please do so and get in touch.) Having compiled Tunnel, you can now run it by issuing the command "C:\Program Files\Java\jdk1.5.0_06\bin\java" -ea -Xmx300m Tunnel.MainBox (or an appropriate variant if your Java path is different). If you have a Tunnel XML directory set up already, you can load it automatically by giving the path to it at the end of the command line. The -Xmx300m option gives Tunnel 300 megabytes of memory to play with; it can be quite memory-hungry, particularly when dealing with very large surveys, so crank up this number if it's being slow. tunnelx-20140102.orig/c.bat0000755000000000000000000000010111762432750012203 0ustar "%JAVA_HOME%\bin\javac" -source 1.4 -target 1.4 -d . src\*.java tunnelx-20140102.orig/src/0000755000000000000000000000000012261213471012055 5ustar tunnelx-20140102.orig/src/SSymbScratch.java0000644000000000000000000004047011762432750015302 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2007 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.Graphics2D; import java.util.Random; import java.io.IOException; import java.lang.StringBuffer; import java.awt.Rectangle; import java.awt.geom.Rectangle2D; import java.awt.geom.Line2D; import java.awt.geom.Point2D; import java.awt.geom.AffineTransform; import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.GeneralPath; import java.awt.geom.Area; import java.awt.BasicStroke; import java.awt.Color; import java.awt.image.Raster; import java.util.Arrays; import java.util.Collections; import java.io.IOException; import java.awt.image.BufferedImage; import javax.imageio.ImageIO; ///////////////////////////////////////////// // persistant class for storing stuff to make symbol layout easily complex. // if there weren't so many, these would be local variables in the functions. class SSymbScratch extends SSymbScratchPath { AffineTransform affscratch = new AffineTransform(); // to make the rotation Random ran = new Random(); // to keep the random generator Line2D axisline = new Line2D.Double(); // axis definitions double apx; double apy; double lenapsq; double lenap; double psx; double psy; double lenpssq; double lenps; // used in rotation. double lenpsap; double dotpsap; double dotpspap; // lattice marking int ilatu; int ilatv; double ilatu0; // lattice phase zero point (integral for type 2) double ilatv0; // here we should put a buffered image which we then plot the // area into at the scale of the lattice in the direction too, // and then should read out the lattice positions from the pixel values // (should be able to rotate by the angle of the lattice, but too hard) // specialize in the large cases where we can thin out the lattice, also use a bigger image BufferedImage latbi = new BufferedImage(220, 220, BufferedImage.TYPE_INT_ARGB);//TYPE_BYTE_BINARY Graphics2D latbiG = (Graphics2D)latbi.getGraphics(); int latbiweff; // effective dimensions when we only use part of it int latbiheff; AffineTransform afflatbiIdent = new AffineTransform(); // identity AffineTransform afflatbi = new AffineTransform(); // used to scale the area down Point2D posbin = new Point2D.Double(); Point2D posbi = new Point2D.Double(); int[] latticpos = new int[131072]; // records the lattice positions which the bitmap says hit the shape int lenlatticpos = -1; // for pullbacks double pbx; // pullback position double pby; double pox; // push out position (which we extend beyond). double poy; double pleng; AffineTransform affnonlate = new AffineTransform(); // non-translation int placeindex = 0; // layout index variables. int placeindexabs = 0; // layout index variable for layoutordered. int noplaceindexlimitpullback = 12; // layout index variables. int noplaceindexlimitrand = 20; // layout index variables. ///////////////////////////////////////////// // this lists the points of the area relative to vector (lapx, lapy) (which has length llenap) centred on (lilatu, lilatv), // and puts them into the array latticpos void SetUpLatticeOfArea(Area lsaarea, OneSSymbol oss, double lapx, double lapy, double llenap, double lilatu, double lilatv) { latbiG.setColor(Color.black); latbiG.setTransform(afflatbiIdent); latbiG.fillRect(0, 0, latbi.getWidth(), latbi.getHeight()); latbiG.setColor(Color.white); Rectangle2D bnd = lsaarea.getBounds2D(); double borframe = llenap / 2; latbiweff = latbi.getWidth(); latbiheff = latbi.getHeight(); double scax = latbiweff / (bnd.getWidth() + 2 * borframe); double scay = latbiheff / (bnd.getHeight() + 2 * borframe); double sca; if (scax <= scay) { sca = scax; latbiheff = Math.min(latbiheff, (int)(latbiheff * scax / scay) + 1); } else { sca = scay; latbiweff = Math.min(latbiweff, (int)(latbiweff * scay / scax) + 1); } afflatbi.setToScale(sca, sca); afflatbi.translate(borframe - bnd.getX(), borframe - bnd.getY()); //double width = llenap; double strokewidth = 1.0 /sca + llenap; // stroke width should be lenap latbiG.setTransform(afflatbi); latbiG.fill(lsaarea); latbiG.setStroke(new BasicStroke((float)strokewidth)); latbiG.draw(lsaarea); // this gives nasty shape sometimes // we should reuse this bitmap for more than one symbol thing //System.out.println("xxxx " + lapx + " " + lapy + " " + llenap + " " + lilatu + " " + lilatv + " " + sca); // find the extent in u and v by transforming the four corners double ulo=0, uhi=0, vlo=0, vhi=0; double llenapsq = llenap * llenap; try { for (int ic = 0; ic < 4; ic++) { posbin.setLocation(((ic == 0) || (ic == 1) ? 0 : latbiweff), ((ic == 0) || (ic == 2) ? 0 : latbiheff)); afflatbi.inverseTransform(posbin, posbi); double u = (lapx * posbi.getX() + lapy * posbi.getY()) / llenapsq - lilatu; double v = (lapy * posbi.getX() - lapx * posbi.getY()) / llenapsq - lilatv; if ((ic == 0) || (u < ulo)) ulo = u; if ((ic == 0) || (u > uhi)) uhi = u; if ((ic == 0) || (v < vlo)) vlo = v; if ((ic == 0) || (v > vhi)) vhi = v; } } catch (NoninvertibleTransformException e) { assert false; } // preview the shape /*try { FileAbstraction file = FileAbstraction.MakeWritableFileAbstraction("biviewlattice.png"); TN.emitMessage("Writing png file " + file.getAbsolutePath() + " with box iu:" + (int)ulo + "<" + (int)uhi + " iv:" + (int)vlo + "<" + (int)vhi); ImageIO.write(latbi, "png", file.localfile); } catch (Exception e) { e.printStackTrace(); } */ // scan the covering lattice lenlatticpos = 0; Raster latbir = latbi.getRaster(); for (int iv = (int)vhi; iv >= vlo; iv--) for (int iu = (int)ulo; iu <= uhi; iu++) { if (lenlatticpos == latticpos.length) { TN.emitWarning("Latispos maxed: " + latticpos.length); break; } // this is in real space pox = lapx * (iu + lilatu) + lapy * (iv + lilatv); poy = lapy * (iu + lilatu) - lapx * (iv + lilatv); // this is in the bitmap space posbin.setLocation(pox, poy); afflatbi.transform(posbin, posbi); int ix = (int)(posbi.getX() + 0.5); int iy = (int)(posbi.getY() + 0.5); // check transform is in bitmap (adding 1 to y because it aligns it better (why?)) if ((ix >= 0) && (ix < latbiweff) && (iy + 1 >= 0) && (iy + 1 < latbiheff) && (latbir.getSample(ix, iy + 1, 0) != 0)) { latticpos[lenlatticpos++] = invLatticePT(iu, iv); } } Arrays.sort(latticpos, 0, lenlatticpos); // so closer points to the origin are early } ///////////////////////////////////////////// void InitAxis(OneSSymbol oss, boolean bResetRand, Area lsaarea) { if (oss.ssb.gsym == null) { TN.emitWarning("No sketch for symbol: " + oss.ssb.gsymname); return; } OnePath apath = oss.ssb.gsym.GetAxisPath(); if (oss.ssb.fpicscale > 0.0) axisline.setLine(apath.pnstart.pn.getX() * oss.ssb.fpicscale, apath.pnstart.pn.getY() * oss.ssb.fpicscale, apath.pnend.pn.getX() * oss.ssb.fpicscale, apath.pnend.pn.getY() * oss.ssb.fpicscale); else axisline.setLine(-apath.pnend.pn.getX() * oss.ssb.fpicscale, -apath.pnend.pn.getY() * oss.ssb.fpicscale, -apath.pnstart.pn.getX() * oss.ssb.fpicscale, -apath.pnstart.pn.getY() * oss.ssb.fpicscale); apx = axisline.getX2() - axisline.getX1(); apy = axisline.getY2() - axisline.getY1(); lenapsq = apx * apx + apy * apy; lenap = Math.sqrt(lenapsq); psx = oss.paxis.getX2() - oss.paxis.getX1(); psy = oss.paxis.getY2() - oss.paxis.getY1(); lenpssq = psx * psx + psy * psy; lenps = Math.sqrt(lenpssq); // set up the lattice stuff lenlatticpos = -1; if (oss.ssb.bBuildSymbolLatticeAcrossArea) { // dot product against what will be the origin of the lattice to translate into coordinate system ilatu0 = (oss.paxis.getX2() * apx + oss.paxis.getY2() * apy) / lenapsq; ilatv0 = (oss.paxis.getX2() * apy - oss.paxis.getY2() * apx) / lenapsq; if (oss.ssb.bSymbolLatticeAcrossAreaPhased) { ilatu0 = (int)(ilatu0 + 0.5); ilatv0 = (int)(ilatv0 + 0.5); } if (lsaarea != null) SetUpLatticeOfArea(lsaarea, oss, apx, apy, lenap, ilatu0, ilatv0); } if (oss.ssb.bBuildSymbolSpreadAlongLine) SetUpPathLength(oss.op); // used in rotation. if (oss.ssb.bRotateable) { lenpsap = lenps * lenap; dotpsap = (lenpsap != 0.0F ? (psx * apx + psy * apy) / lenpsap : 1.0F); dotpspap = (lenpsap != 0.0F ? (-psx * apy + psy * apx) / lenpsap : 1.0F); } else { dotpsap = 1.0; dotpspap = 0.0; } // reset the random seed to make this reproduceable. if (bResetRand) { ran.setSeed(Double.doubleToRawLongBits(apx + apy)); ran.nextInt();ran.nextInt();ran.nextInt();ran.nextInt();ran.nextInt();ran.nextInt();ran.nextInt();ran.nextInt(); } } ///////////////////////////////////////////// boolean BuildAxisTransSetup(OneSSymbol oss, int locindex) { // paxistrans can be null; this sets-up for BuildAxisTransT // position // lattice translation. // we add a lattice translation onto the results of the above // this means we can have a lattice that is slightly jiggled at each point. // pullback point (usually along the axis, unless it's randomized position, then should be closest point) pbx = oss.paxis.getX1(); pby = oss.paxis.getY1(); // position of the symbol pox = oss.paxis.getX2(); poy = oss.paxis.getY2(); // lattice types if (oss.ssb.bBuildSymbolLatticeAcrossArea) { int ilat = 0; if (lenlatticpos > 0) { if (oss.ssb.bSymbolLayoutOrdered) { if (locindex >= lenlatticpos) return false; ilat = latticpos[locindex]; } else if (locindex != 0) // make the first random point at the position of the connective line { // used to be: ilat = latticpos[ran.nextInt(lenlatticpos)]; int mlocindex = (locindex % lenlatticpos); if (mlocindex == 1) { // shuffle list (no shuffle of integer lists function exists) for (int i = lenlatticpos - 1; i >= 2; i--) { int ri = ran.nextInt(i); int s = latticpos[ri]; latticpos[ri] = latticpos[i]; latticpos[i] = s; } } ilat = latticpos[mlocindex]; } } LatticePT(ilat); // return values are ilatu/v pox = apx * (ilatu + ilatu0) + apy * (ilatv + ilatv0); // transformed into real space poy = apy * (ilatu + ilatu0) - apx * (ilatv + ilatv0); } if (oss.ssb.bBuildSymbolSpreadAlongLine) { // pick a random point on line double r; if (oss.ssb.bSymbolLayoutOrdered) { r = locindex * lenap * oss.ssb.faxisscale; if (r > GetCumuPathLength()) return false; } else r = GetCumuPathLength(); double t = ConvertAbstoNodePathLength(r, oss.op); oss.op.Eval(pathevalpoint, pathevaltang, t); pox = pathevalpoint.getX(); poy = pathevalpoint.getY(); } double tanx = dotpsap; double tany = dotpspap; if (oss.ssb.bBuildSymbolSpreadAlongLine) { tanx = pathevaltang.getX(); tany = pathevaltang.getY(); double len = Math.sqrt(tanx * tanx + tany * tany); tanx /= len; tany /= len; } // random dithering if ((locindex != 0) && (oss.ssb.posdeviationprop != 0.0F)) { pbx = pox; // pull-back position is the starting point from which we scatter pby = poy; double sca = oss.ssb.posdeviationprop * lenap * oss.ssb.faxisscale; double scaperp = sca * oss.ssb.faxisscaleperp; double aran = ran.nextGaussian() * sca; double pran = ran.nextGaussian() * scaperp; // force pull-back types to start from full extent if ((oss.ssb.faxisscaleperp != 1.0F) && oss.ssb.bPullback) pran = (pran > 0.0 ? scaperp : -scaperp); pox += tanx * aran + tany * pran; poy += tany * aran - tanx * pran; } // find the length of this pushline double pxv = pox - pbx; double pyv = poy - pby; double plengsq = pxv * pxv + pyv * pyv; pleng = Math.sqrt(plengsq); // rotation. if (oss.ssb.bRotateable) { double a = tanx; double b = tany; boolean bMakeUnit = false; if ((oss.ssb.posangledeviation == -1.0F) && (locindex != 0)) { double angdev = ran.nextDouble() * Math.PI * 2; a = Math.cos(angdev); b = Math.sin(angdev); } else if (oss.ssb.bOrientClosestAlongLine || oss.ssb.bOrientClosestPerpLine) { double t = oss.op.ClosestPoint(pox, poy, -1.0); if (t != -1.0) { oss.op.Eval(pathevalpoint, pathevaltang, t); if (oss.ssb.bOrientClosestAlongLine) { pbx = pathevalpoint.getX(); pby = pathevalpoint.getY(); a = pox - pbx; b = poy - pby; } else { a = pathevaltang.getX(); b = pathevaltang.getY(); } pleng = Math.sqrt(a * a + b * b); a /= pleng; b /= pleng; // something wrong to make this necessary double s = a; a = b; b = -s; } else TN.emitWarning("Failed closest point " + pox + " " + poy); } else if (oss.ssb.bBuildSymbolSpreadAlongLine) { if (oss.ssb.posangledeviation == -2.0) { double s = a; a = b; b = -s; } } else if ((oss.ssb.posangledeviation != 0.0F) && (locindex != 0)) { double angdev = ran.nextGaussian() * oss.ssb.posangledeviation; double ca = Math.cos(angdev); double sa = Math.sin(angdev); a = ca * dotpsap + sa * dotpspap; b = -sa * dotpsap + ca * dotpspap; } affnonlate.setTransform(a, b, -b, a, 0.0F, 0.0F); } else affnonlate.setToIdentity(); // scaling double lenap = Math.sqrt(lenapsq); if (oss.ssb.bScaleable) { double sca = lenps / lenap; affnonlate.scale(sca, sca); } if (oss.ssb.bShrinkby2) { double sca = (ran.nextDouble() + 1.0F) / 2; affnonlate.scale(sca, sca); } affnonlate.translate(-axisline.getX2(), -axisline.getY2()); // scale the picture if (oss.ssb.fpicscale != 1.0) affnonlate.scale(Math.abs(oss.ssb.fpicscale), Math.abs(oss.ssb.fpicscale)); return true; } ///////////////////////////////////////////// AffineTransform BuildAxisTransT(double lam) { // concatenate the default translation AffineTransform res = new AffineTransform(); res.setToTranslation(pbx * (1.0 - lam) + pox * lam, pby * (1.0 - lam) + poy * lam); res.concatenate(affnonlate); return res; } ///////////////////////////////////////////// // this kind of fancy stuff is so we can sort the points // and get the values closer to the origin earlier in the array static int invLatticePT(int iu, int iv) { if ((iu == 0) && (iv == 0)) return 0; int lr = Math.max(Math.abs(iu), Math.abs(iv)); int ld = 2 * lr + 1; int latp; if (iu == lr) { latp = iv + lr; assert latp < ld; } else if (iv == lr) { latp = -iu + lr - 1 + ld; assert latp < 2 * ld - 1; } else if (iu == -lr) { latp = -iv + lr - 2 + 2 * ld; assert latp < 3 * ld - 2; } else { assert iv == -lr; latp = iu + lr - 3 + 3 * ld; } int lat = latp + (ld - 2) * (ld - 2); assert lat < ld * ld; return lat; } ///////////////////////////////////////////// void LatticePT(int lat) { if (lat == 0) { ilatu = 0; ilatv = 0; return; } // find lattice dimension // we may want to work our lattice in the direction of the axis if we have sense. int ld = 1; while (lat >= ld * ld) ld += 2; int lr = (ld - 1) / 2; int latp = lat - (ld - 2) * (ld - 2); if (latp < ld) { ilatu = lr; ilatv = latp - lr; } else if (latp < 2 * ld - 1) { ilatv = lr; ilatu = -(latp - ld + 1 - lr); } else if (latp < 3 * ld - 2) { ilatu = -lr; ilatv = -(latp - 2 * ld + 2 - lr); } else { ilatv = -lr; ilatu = latp - 3 * ld + 3 - lr; } assert lat == invLatticePT(ilatu, ilatv); } } tunnelx-20140102.orig/src/DelTriangulation.java0000644000000000000000000004205312261213471016171 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2012 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.geom.Line2D; import java.awt.geom.Rectangle2D; import java.awt.geom.Area; import java.awt.geom.Point2D; import java.awt.geom.Point2D.Float; import java.awt.geom.GeneralPath; import java.util.List; import java.util.Collections; import java.util.ArrayList; // // // DelTriangulation // // ///////////////////////////////////////////// class DelPoint implements Comparable { Point2D.Float pn; // either it's own object OnePathNode opn = null; // or lifted from OnePathNode RefPathO refpath = null; // or lifted from OnePath float i; // not 0, but 1 for first in path node and -1 for past in path node DelEdge dpedgeconn = null; // one connection public int compareTo(DelPoint dp) { if (pn.x != dp.pn.x) return (pn.x < dp.pn.x ? -1 : 1); if (pn.y != dp.pn.y) return (pn.y < dp.pn.y ? -1 : 1); return 0; } DelPoint(RefPathO lrefpath, float li, float u, float v) { refpath = lrefpath; i = li; //int ir = (refpath.bFore ? refpath.op.nlines - i : i); pn = new Point2D.Float(u, v); } DelPoint(float u, float v) { pn = new Point2D.Float(u, v); } DelPoint(OnePathNode lopn) { opn = lopn; pn = opn.pn; } DelEdge FindEdgeConn(DelPoint dpoth) { DelEdge de = dpedgeconn; do { if (dpoth == (de.a == this ? de.b : de.a)) return de; de = (de.a == this ? de.derightback : de.deleftfore); } while (de != dpedgeconn); return null; } double FindEdgeCross(DelPoint dpoth) { double vx = dpoth.pn.getX() - pn.getX(); double vy = dpoth.pn.getY() - pn.getY(); double vsq = vx*vx + vy*vy; DelEdge de = dpedgeconn; do { DelEdge denext = (de.a == this ? de.derightback : de.deleftfore); DelEdge decross = (denext.a == this ? denext.deleftfore : denext.derightback); double vax = decross.a.pn.getX() - pn.getX(); double vay = decross.a.pn.getY() - pn.getY(); double vbx = decross.b.pn.getX() - pn.getX(); double vby = decross.b.pn.getY() - pn.getY(); double apd = -vax * vy + vay * vx; double bpd = -vbx * vy + vby * vx; if ((apd < 0.0) != (bpd < 0.0)) { double lam = -apd / (bpd - apd); //System.out.println(" lam " + lam); double mua = (vax * vx + vay * vy) / vsq; double mub = (vbx * vx + vby * vy) / vsq; double mu = mua * (1 - lam) + mub * lam; //System.out.println(" mu " + mu); if ((mu > 0.0001) && (mu < 0.9999)) return mu; } de = denext; } while (de != dpedgeconn); return -1.0; } } ///////////////////////////////////////////// class DelEdge { DelPoint a; DelPoint b; DelEdge derightback = null; DelEdge deleftfore = null; int sig = 0; // +1 in right, -1 in left, +2 full outside, -2 full inside DelEdge(DelPoint la, DelPoint lb) { a = la; b = lb; } boolean DEDPsort() { if (a.compareTo(b) == -1) return true; DelPoint c = a; a = b; b = c; DelEdge ldeleftfore = derightback; derightback = deleftfore; deleftfore = ldeleftfore; return false; } boolean PtOnRight(double x, double y) { double vx = b.pn.getX() - a.pn.getX(); double vy = b.pn.getY() - a.pn.getY(); double sx = x - a.pn.getX(); double sy = y - a.pn.getY(); // CPerp(v) = (-vy, vx) double vds = -vy * sx + vx * sy; return vds > 0.0; // later do this properly } boolean RefTriangle() { return ((derightback != null) && (a == derightback.a)); } boolean InTriangle(double x, double y) { if (!RefTriangle()) return false; if (!PtOnRight(x, y)) return false; if (derightback.PtOnRight(x, y)) return false; DelEdge detop = derightback.deleftfore; return ((detop.a == b) == detop.PtOnRight(x, y)); } boolean IsDelauney() { if ((derightback == null) || (deleftfore == null)) return true; DelPoint rp = (derightback.b == a ? derightback.a : derightback.b); DelPoint lp = (deleftfore.b == b ? deleftfore.a : deleftfore.b); //System.out.println(" a " + a.pn.getX() + "," + a.pn.getY()); double sx = (b.pn.getX() - a.pn.getX()) / 2; double sy = (b.pn.getY() - a.pn.getY()) / 2; double vx = rp.pn.getX() - a.pn.getX(); double vy = rp.pn.getY() - a.pn.getY(); double vsq = vx*vx + vy*vy; double ssq = sx*sx + sy*sy; double sdv = sx*vx + sy*vy; double spdv = -sy*vx + sx*vy; assert spdv > -0.0001*ssq; if (spdv < 0.0001*ssq) return !((0.0 <= sdv) && (sdv <= 2*ssq)); double k = (vsq/2 - sdv) / spdv; double rsq = ssq * (1 + k*k); double cx = a.pn.getX() + sx - sy * k; double cy = a.pn.getY() + sy + sx * k; //System.out.println(" x " +(Math.sqrt((rp.pn.getX() - cx)*(rp.pn.getX() - cx) + (rp.pn.getY() - cy)*(rp.pn.getY() - cy)) - Math.sqrt(rsq))); //System.out.println(Math.sqrt((b.pn.getX() - cx)*(b.pn.getX() - cx) + (b.pn.getY() - cy)*(b.pn.getY() - cy)) - Math.sqrt(rsq)); assert Math.abs(Math.sqrt((rp.pn.getX() - cx)*(rp.pn.getX() - cx) + (rp.pn.getY() - cy)*(rp.pn.getY() - cy)) - Math.sqrt(rsq)) < 0.0001; double lvcx = lp.pn.getX() - cx; double lvcy = lp.pn.getY() - cy; double lvcsq = lvcx*lvcx + lvcy*lvcy; return lvcsq >= rsq; } void Flip() { DelPoint la = a; DelPoint lb = b; DelEdge ldeleftfore = deleftfore; DelEdge lderightback = derightback; DelPoint rp = (lderightback.b == la ? lderightback.a : lderightback.b); DelPoint lp = (ldeleftfore.b == lb ? ldeleftfore.a : ldeleftfore.b); DelEdge lderightfore = (a == derightback.b ? derightback.derightback : derightback.deleftfore); assert this == (b == lderightfore.b ? lderightfore.deleftfore : lderightfore.derightback); DelEdge ldeleftback = (b == ldeleftfore.b ? ldeleftfore.derightback : ldeleftfore.deleftfore); assert this == (a == ldeleftback.a ? ldeleftback.derightback : ldeleftback.deleftfore); assert ldeleftback == (ldeleftfore.a == lp ? ldeleftfore.derightback : ldeleftfore.deleftfore); assert lderightfore == (lderightback.b == rp ? lderightback.deleftfore : lderightback.derightback); // disconnect the edge if (lb == lderightfore.b) lderightfore.deleftfore = ldeleftfore; else lderightfore.derightback = ldeleftfore; if (la == ldeleftback.a) ldeleftback.derightback = lderightback; else ldeleftback.deleftfore = lderightback; a.dpedgeconn = lderightback; b.dpedgeconn = ldeleftfore; // reconnect the edge a = lp; b = rp; if (ldeleftfore.a == lp) ldeleftfore.derightback = this; else ldeleftfore.deleftfore = this; derightback = ldeleftback; if (lderightback.b == rp) lderightback.deleftfore = this; else lderightback.derightback = this; deleftfore = lderightfore; DEDPsort(); } } ///////////////////////////////////////////// class DelTriangulation { List dlpointlist; List dledgelist; void MakeInitialBox(Rectangle2D rboundsarea) { float x0 = (float)(rboundsarea.getX() - 10); float y0 = (float)(rboundsarea.getY() - 10); float x1 = (float)(rboundsarea.getX() + rboundsarea.getWidth() + 10); float y1 = (float)(rboundsarea.getY() + rboundsarea.getHeight() + 10); dlpointlist = new ArrayList(); dlpointlist.add(new DelPoint(x0, y0)); dlpointlist.add(new DelPoint(x0, y1)); dlpointlist.add(new DelPoint(x1, y0)); dlpointlist.add(new DelPoint(x1, y1)); assert dlpointlist.get(0).compareTo(dlpointlist.get(1)) == -1; assert dlpointlist.get(1).compareTo(dlpointlist.get(2)) == -1; assert dlpointlist.get(2).compareTo(dlpointlist.get(3)) == -1; dledgelist = new ArrayList(); dledgelist.add(new DelEdge(dlpointlist.get(0), dlpointlist.get(1))); dledgelist.add(new DelEdge(dlpointlist.get(0), dlpointlist.get(3))); dledgelist.add(new DelEdge(dlpointlist.get(0), dlpointlist.get(2))); dledgelist.add(new DelEdge(dlpointlist.get(1), dlpointlist.get(3))); dledgelist.add(new DelEdge(dlpointlist.get(2), dlpointlist.get(3))); dledgelist.get(0).sig = -2; dledgelist.get(2).sig = -2; dledgelist.get(3).sig = -2; dledgelist.get(4).sig = -2; dlpointlist.get(0).dpedgeconn = dledgelist.get(0); dlpointlist.get(1).dpedgeconn = dledgelist.get(0); dlpointlist.get(2).dpedgeconn = dledgelist.get(2); dlpointlist.get(3).dpedgeconn = dledgelist.get(1); dledgelist.get(0).deleftfore = dledgelist.get(3); dledgelist.get(1).deleftfore = dledgelist.get(4); dledgelist.get(1).derightback = dledgelist.get(0); dledgelist.get(2).derightback = dledgelist.get(1); dledgelist.get(3).deleftfore = dledgelist.get(1); dledgelist.get(4).derightback = dledgelist.get(2); } DelEdge FindTriangle(double x, double y) { for (DelEdge de : dledgelist) { if (de.InTriangle(x, y)) return de; } return null; } DelTriangulation(OneSArea osa) { MakeInitialBox(osa.rboundsarea); // insert all the points from the boundary DelPoint ldpprev = null; DelPoint dpfirst = null; List dlboundlist = new ArrayList(); for (RefPathO refpath : osa.refpathsub) { ldpprev = AddDelPoint(new DelPoint(refpath.bFore ? refpath.op.pnstart : refpath.op.pnend)); dlboundlist.add(ldpprev); if (dpfirst == null) dpfirst = ldpprev; float[] pco = refpath.op.GetCoords(); for (int i = 1; i < refpath.op.nlines; i++) { int ir = (refpath.bFore ? i : refpath.op.nlines - i); float x = pco[ir * 2 + 0]; float y = pco[ir * 2 + 1]; ldpprev = AddDelPoint(new DelPoint(refpath, i, x, y)); dlboundlist.add(ldpprev); } } // run through and make sure the boundary points are joined up (inserting new points if necessary) int i = 0; while (i < dlboundlist.size()) { DelPoint dp = dlboundlist.get(i); DelPoint dpfore = dlboundlist.get(i != dlboundlist.size() - 1 ? i + 1 : 0); DelEdge deconn = dp.FindEdgeConn(dpfore); if (deconn == null) { double mu = dp.FindEdgeCross(dpfore); if (mu != -1.0) { double cx = dp.pn.getX() * (1 - mu) + dpfore.pn.getX() * mu; double cy = dp.pn.getY() * (1 - mu) + dpfore.pn.getY() * mu; //DelPoint(RefPathO lrefpath, float li, float u, float v) DelPoint deipoint = new DelPoint((float)cx, (float)cy); AddDelPoint(deipoint); dlboundlist.add(i + 1, deipoint); } else { System.out.println(" mugonewrong i="+i); i++; } } else { deconn.sig = 1; i++; } } // run through and set the boundary signals to show the insides for (int j = 0; j < dlboundlist.size(); j++) { DelPoint dp = dlboundlist.get(j); DelPoint dpprev = (j != 0 ? dlboundlist.get(j - 1) : dlboundlist.get(dlboundlist.size() - 1)); DelPoint dpnext = (j != dlboundlist.size() - 1 ? dlboundlist.get(j + 1) : dlboundlist.get(0)); DelEdge de = dp.dpedgeconn; do { de = (de.a == dp ? de.derightback : de.deleftfore); DelPoint defar = (de.a == dp ? de.b : de.a); if ((defar == dpprev) || (defar == dpnext)) break; } while (de != dp.dpedgeconn); if (de == dp.dpedgeconn) System.out.println(" ffail j="+j); if (de == dp.dpedgeconn) continue; DelEdge desigged = de; boolean binside = false; do { DelPoint defar = (de.a == dp ? de.b : de.a); if (defar == dpprev) binside = true; else if (defar == dpnext) binside = false; else de.sig = (binside ? 2 : -2); de = (de.a == dp ? de.derightback : de.deleftfore); } while (de != desigged); } } DelPoint AddDelPoint(DelPoint dpmid) { DelEdge detriang = FindTriangle(dpmid.pn.getX(), dpmid.pn.getY()); if (detriang == null) return (TN.emitWarning("point not in triangulation area") ? null : null); assert detriang.a == detriang.derightback.a; DelEdge deright = detriang.derightback; DelEdge detop = detriang.derightback.deleftfore; DelEdge de0mid = new DelEdge(detriang.a, dpmid); DelEdge de1mid = new DelEdge(dpmid, detriang.b); DelEdge de2mid = new DelEdge(detriang.derightback.b, dpmid); dpmid.dpedgeconn = de0mid; de0mid.derightback = deright; detriang.derightback = de0mid; de2mid.derightback = detop; deright.deleftfore = de2mid; de1mid.deleftfore = detriang; if (detop.a == detriang.b) detop.derightback = de1mid; else detop.deleftfore = de1mid; de0mid.deleftfore = de1mid; de1mid.derightback = de2mid; de2mid.deleftfore = de0mid; de0mid.DEDPsort(); de1mid.DEDPsort(); de2mid.DEDPsort(); dledgelist.add(de0mid); dledgelist.add(de1mid); dledgelist.add(de2mid); if ((detriang.sig == 0) && !detriang.IsDelauney()) detriang.Flip(); if ((deright.sig == 0) && !deright.IsDelauney()) deright.Flip(); if ((detop.sig == 0) && !detop.IsDelauney()) detop.Flip(); return dpmid; } // then list all the segments here. and put them into their own arrays /* for (RefPathO refpath : osa.refpathsub) { // if going forwards, then everything works if (refpath.bFore) { gparea.append(refpath.op.gp, !bfirst); // the second parameter is continuation, and avoids repeats at the moveto bfirst = false; continue; } // specially decode it if reversed if ((pco == null) || (pco.length < refpath.op.nlines * 6 + 2)); pco = new float[refpath.op.nlines * 6 + 2]; // this gives an array that is interspersed with the control points refpath.op.ToCoordsCubic(pco); } } */ } tunnelx-20140102.orig/src/LineOutputStream.java0000644000000000000000000000701411762432750016216 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.io.FileOutputStream; import java.io.DataOutputStream; import java.io.BufferedWriter; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.io.IOException; // // // LineOutputStream // // ///////////////////////////////////////////// class LineOutputStream { FileAbstraction savefile; DataOutputStream dos = null; // why was this one ever used? does not handle string encoding BufferedWriter bos = null; StringBuffer sb = null; ///////////////////////////////////////////// public LineOutputStream() { sb = new StringBuffer(); } ///////////////////////////////////////////// public LineOutputStream(FileAbstraction lsavefile) throws IOException { savefile = lsavefile; if (savefile != null) { dos = new DataOutputStream(new FileOutputStream(lsavefile.getPath())); TN.emitMessage("Saving file " + savefile.getPath()); } else { sb = new StringBuffer(); //TN.emitWarning("File to save to not specified "); } } ///////////////////////////////////////////// // charsetName="UTF-8" public LineOutputStream(FileAbstraction lsavefile, String charsetName) throws IOException { savefile = lsavefile; if (savefile != null) { bos = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(lsavefile.getPath()), charsetName)); TN.emitMessage("Saving file " + savefile.getPath()+" with charSet: "+charsetName); } else sb = new StringBuffer(); } ///////////////////////////////////////////// public LineOutputStream(DataOutputStream ldos) throws IOException { dos = ldos; TN.emitMessage("Saving on Data output stream"); } ///////////////////////////////////////////// public void WriteLine(String sline) throws IOException { if (dos != null) { dos.writeBytes(sline); dos.writeBytes(TN.nl); } else if (bos != null) bos.append(sline).append(TN.nl); else { sb.append(sline); sb.append(TN.nl); } } ///////////////////////////////////////////// public void Write(String sline) throws IOException { if (dos != null) dos.writeBytes(sline); else if (bos != null) bos.append(sline); else sb.append(sline); } ///////////////////////////////////////////// public void Write(float x, float y) throws IOException { Write(" "); Write(String.valueOf(x)); Write(" "); Write(String.valueOf(y)); } ///////////////////////////////////////////// public void close() throws IOException { if (dos != null) dos.close(); else if (bos != null) bos.close(); } } tunnelx-20140102.orig/src/Quaternion.java0000644000000000000000000000404511762432750015060 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; // // // Quaternion // // class Quaternion { public float w = 1.0F; public float x = 0.0F; public float y = 0.0F; public float z = 0.0F; ///////////////////////////////////////////// void SetXYZ(float lx, float ly, float lz) { x = lx; y = ly; z = lz; w = (float)Math.sqrt(1.0F - (x * x + y * y + z * z)); } ///////////////////////////////////////////// void unit() { w = 1.0F; x = 0.0F; y = 0.0F; z = 0.0F; } ///////////////////////////////////////////// void Mult(Quaternion R, Quaternion L) { w = L.w * R.w - L.x * R.x - L.y * R.y - L.z * R.z; x = L.w * R.x + L.x * R.w + L.y * R.z - L.z * R.y; y = L.w * R.y + L.y * R.w + L.z * R.x - L.x * R.z; z = L.w * R.z + L.z * R.w + L.x * R.y - L.y * R.x; } ///////////////////////////////////////////// void VecRot(Vec3 f, Vec3 t) { x = f.y * t.z - f.z * t.y; y = f.z * t.x - f.x * t.z; z = f.x * t.y - f.y * t.x; w = f.x * t.x + f.y * t.y + f.z * t.z; } ///////////////////////////////////////////// void SetFrom(Quaternion q) { x = q.x; y = q.y; z = q.z; w = q.w; } }; tunnelx-20140102.orig/src/SvxFileDialog.java0000644000000000000000000002537612261213471015435 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.io.File; import javax.swing.JFrame; import javax.swing.filechooser.*; import javax.swing.JFileChooser; import javax.swing.filechooser.FileFilter; import javax.swing.JOptionPane; import javax.swing.JApplet; ///////////////////////////////////////////// class SvxFileFilter extends FileFilter { StringBuffer desc = new StringBuffer(); String[] ftext; ///////////////////////////////////////////// SvxFileFilter(String ftname, String[] lftext) { ftext = lftext; // make the description desc.append(ftname); desc.append(" Files ("); for (int i = 0; i < ftext.length; i++) { if (i != 0) desc.append(", "); desc.append("*."); desc.append(ftext[i]); } desc.append(")"); } ///////////////////////////////////////////// SvxFileFilter(String namedirectory) { desc.append(namedirectory); ftext = null; } ///////////////////////////////////////////// public boolean accept(File file) { if (file.isDirectory()) return true; if (ftext == null) return false; String suff = TN.getSuffix(file.getName()); // need a coherent interface for this function. if ((suff == null) || suff.equals("") || (suff.charAt(0) != '.')) return false; suff = suff.substring(1); for (int i = 0; i < ftext.length; i++) if (suff.equalsIgnoreCase(ftext[i])) return true; return false; } ///////////////////////////////////////////// public String getDescription() { return desc.toString(); } }; ///////////////////////////////////////////// ///////////////////////////////////////////// // the loading dialog public class SvxFileDialog extends JFileChooser { static final int FT_ANY = 0; static final int FT_SVX = 1; static final int FT_XSECTION_PREVIEW = 2; static final int FT_SYMBOLS = 3; static final int FT_VRML = 4; static final int FT_BITMAP = 5; static final int FT_TH2 = 6; static final int FT_XMLSKETCH = 7; static final int FT_DIRECTORY = 8; static final int FT_VECTOR = 9; static String[] ftnames = { "Any", "SVX/DistoX", "XSection Preview", "Symbols", "VRML", "Bitmap", "Therion sketch", "Tunnel sketch", "Directory", "Vector" }; static String[][] ftexts = { { "*" }, { "svx", "txt", "top" }, { "??" }, { "??" }, { "wrl" }, { "png", "jpg", "bmp", "gif" }, { "th2" }, { "xml" }, { "??" }, { "svg" } }; FileAbstraction svxfile = null; FileAbstraction tunneldirectory = null; boolean bReadCommentedXSections; ///////////////////////////////////////////// SvxFileDialog(FileAbstraction currentDirectory) { super(currentDirectory.localfile); if (!currentDirectory.getName().equals("")) setSelectedFile(currentDirectory.localfile); // filechooser function } ///////////////////////////////////////////// FileAbstraction getCurrentDirectoryA() { return FileAbstraction.MakeDirectoryFileAbstractionF(getCurrentDirectory()); } ///////////////////////////////////////////// // this fixes up the suffix when someone types it in wrong FileAbstraction getSelectedFileA(int ftype, boolean bsaving) { File fil = getSelectedFile(); String fsel = fil.toString(); //int fselxfiletype = fil.xfiletype; // doesn't work because selected file is File not FileAbstraction String suff = TN.getSuffix(fil.getName()); if (ftype == FT_DIRECTORY) { if (!fsel.endsWith("/")) fsel = fsel + "/"; // the dialog box removes necessary trailing slashes when we abuse it to enter in URLs tunneldirectory = FileAbstraction.MakeOpenableFileAbstraction(fsel); if (!tunneldirectory.isDirectory()) return null; tunneldirectory.xfiletype = FileAbstraction.FA_DIRECTORY; tunneldirectory.bIsDirType = true; return tunneldirectory; } // append correct suffixes if the user failed to add them else if (ftype == FT_SVX) { if (!suff.equalsIgnoreCase(TN.SUFF_SVX)) TN.emitWarning("wrong suffix for SVX file"); assert !bsaving; // we don't save svx files yet //assert fselxfiletype == FA_FILE_SVX; } else if (ftype == FT_XMLSKETCH) { if (!suff.equalsIgnoreCase(TN.SUFF_XML)) { TN.emitWarning("wrong suffix for XML file"); if (bsaving) { TN.emitWarning("setting suffix of file to .xml"); fsel = fsel + TN.SUFF_XML; //fselxfiletype = FA_FILE_XML_SKETCH; } } //else // assert fselxfiletype == FileAbstraction.FA_FILE_XML_SKETCH; } svxfile = FileAbstraction.MakeOpenableFileAbstraction(fsel); //svxfile.xfiletype = fselxfiletype; return svxfile; } ///////////////////////////////////////////// void SetFileFil(int ftype) { SvxFileFilter sff = (ftype != FT_DIRECTORY ? new SvxFileFilter(ftnames[ftype], ftexts[ftype]) : new SvxFileFilter(ftnames[ftype])); //TN.emitMessage(sff.getDescription()); try { addChoosableFileFilter(sff); setFileFilter(sff); } catch (NullPointerException e) { TN.emitWarning(e.toString()); } } ///////////////////////////////////////////// static SvxFileDialog showOpenDialog(FileAbstraction currentDirectory, JApplet frame, int ftype, boolean bAuto) { System.out.println("Can't do this from an applet"); return null; } ///////////////////////////////////////////// static SvxFileDialog showOpenDialog(FileAbstraction currentDirectory, JFrame frame, int ftype, boolean bAuto) { // weird getting the suffix of a directory? // maybe something's bee posted into it String lsuff = TN.getSuffix(currentDirectory.getName()); boolean bBlankFile = (!lsuff.equalsIgnoreCase(TN.SUFF_SVX) && !currentDirectory.getName().equals("")); //SvxFileDialog sfd = new SvxFileDialog((bBlankFile ? currentDirectory.getParentFile() : currentDirectory)); SvxFileDialog sfd = new SvxFileDialog(currentDirectory); sfd.SetFileFil(ftype); sfd.svxfile = null; sfd.tunneldirectory = null; sfd.setDialogTitle("Open " + ftnames[ftype] + "File"); sfd.setFileSelectionMode(ftype != FT_DIRECTORY ? JFileChooser.FILES_ONLY : JFileChooser.DIRECTORIES_ONLY); FileAbstraction file; if (!bAuto) { if (sfd.showOpenDialog(frame) != JFileChooser.APPROVE_OPTION) return null; file = sfd.getSelectedFileA(ftype, false); } else file = currentDirectory; // directory type TN.emitMessage("ft type=" + ftype + " " + FT_DIRECTORY + " " + file + " isDirectory=" + file.isDirectory()); if (ftype == FT_DIRECTORY) { if ((file.localurl == null) && !file.isDirectory()) // adding in localurl condition as real hack to get the tutorial loading return null; sfd.tunneldirectory = file; sfd.tunneldirectory.xfiletype = FileAbstraction.FA_DIRECTORY; sfd.tunneldirectory.bIsDirType = true; return sfd; } // get rid of directories if ((file.localurl == null) && file.isDirectory()) return null; String suff = TN.getSuffix(file.getName()); sfd.bReadCommentedXSections = (suff.equalsIgnoreCase(TN.SUFF_SVX) || suff.equalsIgnoreCase(TN.SUFF_TOP)); TN.emitMessage(currentDirectory.toString() + " kkkkk " + suff + " " + ftype + " " + suff.equalsIgnoreCase(TN.SUFF_SVX)); if ((ftype == FT_TH2) || suff.equalsIgnoreCase(TN.SUFF_WALLS)) { sfd.svxfile = file; return sfd; } if (ftype == FT_BITMAP) { sfd.svxfile = file; sfd.svxfile.xfiletype = FileAbstraction.FA_FILE_IMAGE; return sfd; } if (suff.equalsIgnoreCase(TN.SUFF_SVX)) { sfd.svxfile = file; sfd.svxfile.xfiletype = FileAbstraction.FA_FILE_SVX; TN.emitWarning("shouldbesuffsvx " + sfd.svxfile.xfiletype); return sfd; } if (suff.equalsIgnoreCase(TN.SUFF_TXT)) { sfd.svxfile = file; sfd.svxfile.xfiletype = file.GetFileType(); if (sfd.svxfile.xfiletype == FileAbstraction.FA_FILE_POCKET_TOPO) return sfd; } if (suff.equalsIgnoreCase(TN.SUFF_TOP)) { sfd.svxfile = file; sfd.svxfile.xfiletype = file.GetFileType(); if (sfd.svxfile.xfiletype == FileAbstraction.FA_FILE_POCKET_BINTOP) return sfd; } if (suff.equalsIgnoreCase(TN.SUFF_XML) && (ftype == FT_XMLSKETCH)) { sfd.svxfile = file; //sfd.svxfile.xfiletype = FileAbstraction.FA_FILE_XML_SKETCH; (look it up?) return sfd; } TN.emitWarning("Unknown File Type on:" + file.getName()); JOptionPane.showMessageDialog(frame, "Unknown File Type on:" + file.getName()); return null; } ///////////////////////////////////////////// static SvxFileDialog showSaveDialog(FileAbstraction currentDirectory, JApplet frame, int ftype, boolean bauto) { return null; } ///////////////////////////////////////////// static SvxFileDialog showSaveDialog(FileAbstraction currentDirectory, JFrame frame, int ftype, boolean bauto) { FileAbstraction savetype = null; if (currentDirectory.localurl != null) currentDirectory = TN.currentDirectory; else if (currentDirectory.getName().equals("")) currentDirectory = currentDirectory; else currentDirectory = FileAbstraction.MakeDirectoryAndFileAbstraction(currentDirectory.getParentFile(), TN.setSuffix(currentDirectory.getName(), "." + ftexts[ftype][0])); SvxFileDialog sfd = new SvxFileDialog(currentDirectory); sfd.SetFileFil(ftype); sfd.svxfile = null; sfd.tunneldirectory = null; sfd.setDialogTitle("Save " + ftnames[ftype] + "File"); sfd.setFileSelectionMode(ftype != FT_DIRECTORY ? JFileChooser.FILES_ONLY : JFileChooser.DIRECTORIES_ONLY); if (!bauto && (sfd.showSaveDialog(frame) != JFileChooser.APPROVE_OPTION)) return null; FileAbstraction file = sfd.getSelectedFileA(ftype, true); return sfd; } } tunnelx-20140102.orig/src/SVGPaths.java0000644000000000000000000000750311762432750014374 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2006 Martin Green, Julian Todd // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.util.List; import java.io.IOException; import java.lang.String; import java.awt.geom.PathIterator; class SVGPaths { private float tunnelunit = 0.1F; //length of tunnel unit in meters private float xoffset = 0F; private float yoffset = 0F; private int id = 0; //The next id to use public SVGPaths(LineOutputStream los, List vpaths) throws IOException { WriteHeader(los); for (OnePath op : vpaths) WritePath(los, op); WriteFooter(los); } // open and close void WriteHeader(LineOutputStream los) throws IOException { TNXML.chconvleng = TNXML.chconvlengWSP; // a complete hack to stop &space; getting in here assert false; // not used los.WriteLine("\n"); los.WriteLine(""); los.WriteLine(TNXML.xcomopen(0, "svg", "xmlns", "http://www.w3.org/2000/svg", "version", "1.1")); los.WriteLine(TNXML.xcomtext(1, "title", "Tunnels Paths")); los.WriteLine(TNXML.xcomtext(1, "desc", "This file solely contains the definitions of paths for Tunnel, you need a view.svg file to see anything.")); los.WriteLine(TNXML.xcomopen(1, "defs")); } void WriteFooter(LineOutputStream los) throws IOException { los.WriteLine(TNXML.xcomclose(1, "defs")); los.WriteLine(TNXML.xcomclose(0, "svg")); TNXML.chconvleng = TNXML.chconvlengWSP; } static float[] coords = new float[6]; //Used to get the position of line segments void WritePath(LineOutputStream los, OnePath op) throws IOException { //Set svg id to path String sid = new String(String.valueOf(this.id)); op.svgid = this.id; this.id=this.id+1; //Generate list of linestyles and classes String classes = new String(SketchLineStyle.shortlinestylenames[op.linestyle]); for (int j = 0; j < op.vssubsets.size(); j++) classes = classes + " " + SketchLineStyle.shortlinestylenames[op.linestyle] + op.vssubsets.get(j); //Generate d the list of commands to generate points String d = op.svgdvalue(0.0F, 0.0F); //Set parameters and attributes based on if the heights are set int numparam=0; // It's poss that after UpdateZnodes all nodes are set //if (op.pnstart.bzaltset) // numparam = 10; //else numparam = 6;//need to determine why bzaltset is not set on 'update node z' //If you update z alt and change the 6 to 10 it does give all z heights String parameters[] = {"id", sid, "class", classes, "d", d, "z0", String.valueOf(op.pnstart.zalt), "z1", String.valueOf(op.pnend.zalt)}; //Determine if the path has funny attributes if (op.plabedl!=null) { los.WriteLine(TNXML.xcomopenN(2, "path", parameters, numparam)); op.plabedl.WriteXML(los,3,false); los.WriteLine(TNXML.xcomclose(2, "path")); } else { los.WriteLine(TNXML.xcomN(2, "path", parameters, numparam)); } } } tunnelx-20140102.orig/src/TunnelTopParser.java0000644000000000000000000004471012261213471016033 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2011 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // FoUndation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; // See TopParser/readtop.py for the source code import java.awt.geom.Line2D; import java.util.List; import java.util.ArrayList; import java.util.Date; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.awt.Font; import java.awt.Color; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D.Float; import java.io.IOException; import java.io.BufferedReader; import java.io.InputStream; import java.io.Reader; import java.io.StringReader; import java.io.FileReader; import java.io.StreamTokenizer; import java.io.InputStreamReader; class TOPxsection { int x; int y; String stn; float direction; TOPxsection(InputStream inp) throws IOException { x = TunnelTopParser.ReadInt4(inp); y = TunnelTopParser.ReadInt4(inp); stn = TunnelTopParser.ReadStn(inp); int idirection = TunnelTopParser.ReadInt4(inp); if (idirection != -1) direction = TunnelTopParser.adegrees(idirection); else direction = -1.0f; System.out.println("Xsection "+ x +" "+y+" "+stn+" "+direction); } } class TOPpolygon { int[] poly; int col; TOPpolygon(InputStream inp) throws IOException { //System.out.println("Polygon"); int a = TunnelTopParser.ReadInt4(inp); poly = new int[a*2]; for (int i = 0; i 340.0)); double sumdist = 0.0; double suminclination = 0.0; double sumazimuth = 0.0; String sumcomment = ""; for (TOPleg ntopleg = this; ntopleg != null; ntopleg = ntopleg.topleglink) { sumdist += ntopleg.dist; suminclination += ntopleg.inclination; sumazimuth += ntopleg.azimuth + (bazimuthnearzero && (ntopleg.azimuth < 180.0) ? 360.0 : 0.0); if (!ntopleg.comment.equals("")) sumcomment += ntopleg.comment+" "; nduplicates++; } double avgdist = sumdist / nduplicates; double avginclination = suminclination / nduplicates; double avgazimuth = sumazimuth / nduplicates; double extdist = 0.0; double extinclination = 0.0; double extazimuth = 0.0; for (TOPleg ntopleg = this; ntopleg != null; ntopleg = ntopleg.topleglink) { extdist = Math.max(extdist, Math.abs(avgdist - ntopleg.dist)); extinclination = Math.max(extinclination, Math.abs(avginclination - ntopleg.inclination)); extazimuth = Math.max(extazimuth, Math.abs(avgazimuth - (ntopleg.azimuth + (bazimuthnearzero && (ntopleg.azimuth < 180.0) ? 360.0 : 0.0)))); } String exts = ""; if ((extdist > 0.05) || (extinclination > 0.5) || (extazimuth > 0.5)) exts = String.format(" ext:%.1f,%.1f,%.1f ", extdist, extinclination, extazimuth); if (avgazimuth >= 360.0) avgazimuth -= 360.0; String sflip = (bflip ? " " + TN.flipCLINEsignal : ""); return String.format("%s\t%s\t%.3f\t%.1f\t%.1f%s%s%s%s", fromstn, tostn, avgdist, avgazimuth, avginclination, sflip, exts, sumcomment, TN.nl); } } ///////////////////////////////////////////// class TunnelTopParser { int version; List planxsections = new ArrayList(); List elevxsections = new ArrayList(); StringBuilder sbsvx = new StringBuilder(); StringBuilder sbsvxsplay = new StringBuilder(); // look in LoadTopoSketch() in PocketTopoLoader.java List vpathsplan = new ArrayList(); List vpathselev = new ArrayList(); static float TOPFILE_SCALE = 0.001F; // it's in milimetres ///////////////////////////////////////////// static float adegrees(int bangle) { return 360*(float)bangle / 65536; } ///////////////////////////////////////////// static int ReadInt2(InputStream inp) throws IOException { int b0 = inp.read(); int b1 = inp.read(); int res = b0 + (b1 << 8); //System.out.println("eee "+b0+" "+b1+" "+res); return res; } ///////////////////////////////////////////// static int ReadInt4(InputStream inp) throws IOException { int b0 = inp.read(); int b1 = inp.read(); int b2 = inp.read(); int b3 = inp.read(); int res = b0 + (b1 << 8) + (b2 << 16) + (b3 << 24); //System.out.println("eee "+b0+" "+b1+" "+b2+" "+b3+" "+res); return res; } long ReadInt8(InputStream inp) throws IOException { long b0 = inp.read(); long b1 = inp.read(); long b2 = inp.read(); long b3 = inp.read(); long b4 = inp.read(); long b5 = inp.read(); long b6 = inp.read(); long b7 = inp.read(); long res = b0 + (b1 << 8) + (b2 << 16) + (b3 << 24) + (b4 << 32) + (b5 << 40) + (b6 << 48) + (b7 << 56); //System.out.println("eee "+b0+" "+b1+" "+b2+" "+b3+" "+res); return res; } ///////////////////////////////////////////// Date ReadDate(InputStream inp) throws IOException { long i1 = ReadInt4(inp); long i2 = ReadInt4(inp); long si = i1 + (i2<<32); long sit = (si - 621355968000000000L) / 10000; Date date = new Date(sit); System.out.println(date); return date; // ticks = struct.unpack(' stationnodes) throws IOException { //System.out.println("Polygon"); int a = TunnelTopParser.ReadInt4(inp); //System.out.println(col); float xdisplace = 0.0F; int x0 = TunnelTopParser.ReadInt4(inp); int y0 = TunnelTopParser.ReadInt4(inp); OnePathNode lpnstart = FindStationNode(null, x0, y0, stationnodes, xdisplace); OnePath op = new OnePath(lpnstart); for (int i = 1; i xsections, List toppaths, InputStream inp, List stationnodes) throws IOException { Rectangle2D res = null; mapping(inp); while (true) { int element = inp.read(); if (element == -1) break; // end of file! if (element == 0) break; if (element == 1) { OnePath topop = readTOPpolygon(inp, stationnodes); if (res == null) res = topop.getBounds(null).getBounds2D(); else res.add(topop.getBounds(null)); toppaths.add(topop); } else if (element == 3) xsections.add(new TOPxsection(inp)); else TN.emitError("TOP Element number ["+element+"] not defined"); } return res; } ///////////////////////////////////////////// void mapping(InputStream inp) throws IOException { //Gets the centre point of screen and scale of different views int X = ReadInt4(inp); int Y = ReadInt4(inp); int scale = ReadInt4(inp); System.out.println(X +" "+ Y +" "+ scale); } ///////////////////////////////////////////// static OnePathNode FindStationNode(String stn, int x, int y, List stationnodes, float xdisplace) { for (OnePathNode opn : stationnodes) { if (stn.equals(opn.pnstationlabel)) return opn; } // make new node in case of the sketch OnePathNode opn = new OnePathNode(x * TOPFILE_SCALE * TN.CENTRELINE_MAGNIFICATION + xdisplace, y * TOPFILE_SCALE * TN.CENTRELINE_MAGNIFICATION, 0.0F); opn.pnstationlabel = stn; return opn; } ///////////////////////////////////////////// String GetSVX() { return sbsvx.toString(); } boolean bsingledashsplays = false; ///////////////////////////////////////////// boolean ParseTOPFile(FileAbstraction tfile) { try { InputStream inp = tfile.GetInputStream(); byte[] htop = new byte[3]; inp.read(htop, 0, 3); System.out.println(new String(htop)); assert "Top".equals(new String(htop)); version = inp.read(); int ntrips = ReadInt4(inp); TN.emitWarning("We have a top file version " + version + " containing "+ntrips+" trips"); int lntrips = Math.max(ntrips, 1); // avoid array out of bounds exception when ntrips=0. Date[] dates = new Date[lntrips]; String[] comments = new String[lntrips]; float[] declination = new float[lntrips]; for (int i = 0; i < ntrips; i++) { dates[i] = ReadDate(inp); comments[i] = ReadComments(inp); declination[i] = adegrees(ReadInt2(inp)); } //legs/shots int tripcount = 0; sbsvx.append("*begin "+ tfile.getSketchName() + TN.nl); sbsvx.append(";*require 1.????"+ TN.nl+ TN.nl); tripcomments(sbsvx, comments[tripcount], dates[tripcount], declination[tripcount]); int currenttrip = -1; int currentdirection = -1; sbsvx.append("*data normal from to tape compass clino ignoreall"+ TN.nl); int nshots = ReadInt4(inp); //sbsvx.append((r'\n',r'\n;',comments[tripcount]) + TN.nl); List toplegs = new ArrayList(); for (int i = 0; i < nshots; i++) { //Station String fromstn = ReadStn(inp); String tostn = ReadStn(inp); int dist = ReadInt4(inp); float azimuth = adegrees(ReadInt2(inp)); float inclination = adegrees(ReadInt2(inp)); if (inclination > 180.0F) inclination = inclination - 360.0F; int flags = inp.read(); int roll = inp.read(); int tripindex = ReadInt2(inp); String comment = ""; //bit 1 of flags is flip (left or right) //bit 2 of flags indicates a comment boolean bflip = ((flags & 1) == 1); if ((flags & 2) == 2) comment = ReadComments(inp); // this accounts for the missing flips // load into pockettopo to see if we can account for it!!! //if (fromstn.equals("1-0") || fromstn.equals("1-1") || fromstn.equals("1-2") || fromstn.equals("5-3")) // bflip = true; //System.out.println("Flipflags="+flags+" on "+fromstn+" "+tostn); // not sure what this bit is about, but have cleaned it up [maybe to do with survex extended elevations] if (i == 0) { currenttrip = tripindex; currentdirection = (flags & 1); //assert(tostn.equals("-")); //sbsvx.append((currentdirection == 1 ? "*eleft " : "*eright ") + fromstn +TN.nl); } else { if (currenttrip != tripindex); { //tripcomments(sbsvx, comments[tripcount], dates[tripcount], declination[tripcount]); tripcount++; currenttrip = tripindex; } } TOPleg ntopleg = new TOPleg(fromstn, tostn, dist/1000.0, azimuth, inclination, 360*roll/256.0, tripindex, bflip, comment); if ((toplegs.size() == 0) || !toplegs.get(toplegs.size() - 1).MergeDuplicate(ntopleg)) toplegs.add(ntopleg); } if (toplegs.size() != 0) sbsvx.append("*fix "+toplegs.get(0).fromstn+" 0 0 0 ; default fix"+TN.nl+TN.nl); for (TOPleg topleg : toplegs) if (!topleg.tostn.equals("-")) sbsvx.append(topleg.toString()); sbsvx.append(TN.nl); sbsvx.append(";;;;;;;;;;;;"+TN.nl); sbsvx.append("*flags splay"+TN.nl); int nsplaycount = 1; for (TOPleg topleg : toplegs) { if (topleg.tostn.equals("-")) { // this -n- format then can also be stripped out by FileAbstraction.RunSurvex if (!bsingledashsplays) topleg.tostn = "-"+nsplaycount+"-"; sbsvx.append(topleg.toString()); nsplaycount++; } } sbsvx.append("*end "+ tfile.getSketchName()); sbsvx.append(TN.nl); //System.out.println(tfile.getSketchName()); //Reference stations int nrefstn = ReadInt4(inp); System.out.println("Stn NS EW "+nrefstn); for (int i = 0; i < nrefstn; i++) { String stn = ReadStn(inp); long east = ReadInt8(inp); long west = ReadInt8(inp); int altitute = ReadInt2(inp); String comment = ReadComments(inp); } //Overview Mapping information (not needed by import) mapping(inp); List stationnodes = new ArrayList(); Rectangle2D planrect = ReadDrawing(planxsections, vpathsplan, inp, stationnodes); Rectangle2D elevrect = ReadDrawing(elevxsections, vpathselev, inp, stationnodes); TN.emitMessage(" planrect "+planrect); TN.emitMessage(" elevrect "+elevrect); inp.close(); // example single path intop the file // look in LoadTopoSketch() in PocketTopoLoader.java for more information (and how to do centrelines) } catch (IOException e) { TN.emitWarning(e.toString()); } return false; } } /* def station(F): #id's split into major.decimal(minor) idd = struct.unpack(' subsets = new HashSet(); List vsareas = new ArrayList(); Area uarea = new Area(); Set adjoiningsubsetsbelow = new HashSet(); Set adjoiningsubsetsabove = new HashSet(); }; ///////////////////////////////////////////// class TSublevelmapping implements Comparable { String subcolour; double zsum = 0.0; double zweight = 0.0; float zlo = 0.0F; float zhi = 0.0F; int npaths = 0; // parallel to opsframesla List slm = new ArrayList(); Area uareaA = new Area(); String Drep() { double l1 = zsum / (zweight != 0.0 ? zweight : 1.0); return "paths: " + npaths + " z: " + l1 + " ss ";// + (subsets.isEmpty() ? "" : subsets.iterator().next()); } TSublevelmapping(String lsubcolour, int n) { subcolour = lsubcolour; for (int i = 0; i < n; i++) slm.add(new TSublevelmappingL()); } public int compareTo(TSublevelmapping tsl) { double l1 = zsum / (zweight != 0.0 ? zweight : 1.0); double l2 = tsl.zsum / (tsl.zweight != 0.0 ? tsl.zweight : 1.0); double d = l1 - l2; if (d < 0.0F) return +1; if (d > 0.0F) return -1; return 0; } ///////////////////////////////////////////// void FindAdjoiningSubsets(TSublevelmapping tslabove, TSublevelmapping tslbelow, List opsframesla) { assert (tslabove == null) || (tslabove.slm.size() == slm.size()); assert (tslbelow == null) || (tslbelow.slm.size() == slm.size()); for (int i = 0; i < slm.size(); i++) { TSketchLevelArea sla = opsframesla.get(i); TSublevelmappingL sl = slm.get(i); assert sl.adjoiningsubsetsbelow.isEmpty() && sl.adjoiningsubsetsabove.isEmpty(); for (OneSArea osa : sl.vsareas) { for (RefPathO rpo : osa.refpathsub) { if (rpo.op.gp.intersects(sla.rectframeRS)) for (String subset : rpo.op.vssubsets) { if ((tslabove != null) && tslabove.slm.get(i).subsets.contains(subset)) sl.adjoiningsubsetsabove.add(subset); if ((tslbelow != null) && tslbelow.slm.get(i).subsets.contains(subset)) sl.adjoiningsubsetsbelow.add(subset); } } } System.out.println(i + "aaajoininin " + sl.adjoiningsubsetsabove.size() + " " + sl.adjoiningsubsetsbelow.size()); } } void clear() { for (int i = 0; i < slm.size(); i++) { TSublevelmappingL sl = slm.get(i); sl.vsareas.clear(); sl.uarea.reset(); sl.adjoiningsubsetsbelow.clear(); sl.adjoiningsubsetsabove.clear(); } npaths = 0; zsum = 0.0; zweight = 0.0; uareaA.reset(); } } ///////////////////////////////////////////// class TSketchLevelArea { Set pathspresent = new HashSet(); Set pathsintersecting = new HashSet(); Set areaspresent = new HashSet(); Set subsetspresent = new HashSet(); OnePath opframe; SketchFrameDef sketchframedef; OneSketch fsketch; AffineTransform pframesketchtransinverse; Area areaframeRS; // in drawing space Rectangle2D rectframeRS; Area rectframeRSA; // find survex data to use as mapping from *title Map subsetexplorermap = new HashMap(); SurvexLoaderNew sln; // workspace Set retainsubsets = new HashSet(); Set greyedsubsets = new HashSet(); Set brightgreysubsets = new HashSet(); TSketchLevelArea(OnePath lopframe) { opframe = lopframe; sketchframedef = lopframe.plabedl.sketchframedef; fsketch = sketchframedef.pframesketch; } ///////////////////////////////////////////// void FindAreasPathsPresent() { // discover the paths and subsets in the framed sketch pathspresent.clear(); pathsintersecting.clear(); areaspresent.clear(); for (OneSArea osa : fsketch.vsareas) { if (osa.aarea.intersects(rectframeRS)) { areaspresent.add(osa); for (RefPathO rpo : osa.refpaths) { if (rpo.op.linestyle != SketchLineStyle.SLS_CENTRELINE) pathspresent.add(rpo.op); } } } // also look for subset pair adjacencies (edges that span two levels) and their adjacent subsets (areas) for (OnePath op : fsketch.vpaths) if ((op.linestyle != SketchLineStyle.SLS_CONNECTIVE) && op.gp.intersects(rectframeRS)) // do we have to worry about labels? pathsintersecting.add(op); pathspresent.addAll(pathsintersecting); for (OnePath op : pathspresent) subsetspresent.addAll(op.vssubsets); subsetspresent.retainAll(sketchframedef.submapping.keySet()); } ///////////////////////////////////////////// String FindCommonSubsetA(OneSArea osa) { //Set commonsubsets = new HashSet(); Set commonsubsets = new HashSet(sketchframedef.submapping.keySet()); for (RefPathO rpo : osa.refpathsub) { if (!commonsubsets.isEmpty()) { commonsubsets.retainAll(rpo.op.vssubsets); if (commonsubsets.isEmpty()) return null; } else commonsubsets.addAll(rpo.op.vssubsets); } return commonsubsets.iterator().next(); } ///////////////////////////////////////////// void SetExplorerMap() { String survexstring = ""; for (OnePath op : fsketch.vpaths) { if ((op.linestyle == SketchLineStyle.SLS_CONNECTIVE) && (op.plabedl != null) && op.plabedl.sfontcode.equals("survey")) { if (op.plabedl.drawlab.length() > survexstring.length()) survexstring = op.plabedl.drawlab; } } // parse the survex string sln = new SurvexLoaderNew(); sln.InterpretSvxText(survexstring); for (OneLeg ol : sln.vlegs) { if ((ol.svxtitle.length() > 0) && (subsetexplorermap.get(ol.svxtitle) == null)) { String tline = ol.svxdate + " " + ol.svxtitle + ":\n%10/1%\n;" + ol.svxteam; subsetexplorermap.put(ol.svxtitle, tline); } } } }; ///////////////////////////////////////////// class RBDVal implements Comparable { String s; int c = 1; RBDVal(String ls) { s = ls; } public int compareTo(RBDVal oth) { if (c != oth.c) return oth.c - c; return s.compareTo(oth.s); } } ///////////////////////////////////////////// class AtlasGenerator { List vpathsatlas = new ArrayList(); // output String commonsubset; // primary frame and its paths within it OneSArea osaframe = null; List opsframeslaP = new ArrayList(); // for indexOf List opsframesla = new ArrayList(); // the border overlap frame OneSArea osaframeborder = null; List opsframeborder = new ArrayList(); // should be arranged to be corresponding to the above list SketchFrameDef sketchframedefborder = null; // should handle as a list osaframe.sketchframedefs float framescaledown; // common to all framed sketches // for the thumbnail stuff OneSArea osaframethumb = null; float thumbframescaledown; // for the picture bit OneSArea osaframepicture = null; // information per level that the subsets all map into // the mapping is sketchframedef.submapping // we don't allow for the default subset // for multiple sketchframedefs we can contatenate a hashkey for each sketchframedef to make the mapping unique Map subcolmap = new HashMap(); ///////////////////////////////////////////// static String FindCommonSubset(OneSketch asketch) { // find the primary subset Set commonsubsets = new HashSet(); for (OnePath op : asketch.vpaths) { if (!commonsubsets.isEmpty()) { commonsubsets.retainAll(op.vssubsets); if (commonsubsets.isEmpty()) return null; } else commonsubsets.addAll(op.vssubsets); } return commonsubsets.iterator().next(); } ///////////////////////////////////////////// List FindExplorers() { Map rres = new HashMap(); for (int i = 0; i < opsframesla.size(); i++) { TSketchLevelArea sla = opsframesla.get(i); for (OnePath op : sla.fsketch.vpaths) { if (op.linestyle != SketchLineStyle.SLS_CENTRELINE) continue; if (!op.gp.intersects(sla.rectframeRS)) continue; boolean bretained = false; String team = null; for (String subset : op.vssubsets) { if (sla.retainsubsets.contains(subset)) bretained = true; String lteam = sla.subsetexplorermap.get(subset); if (lteam != null) team = lteam; } if (bretained) { if (team == null) { String title = sla.sln.FindStationTitle(op); if (title != null) team = sla.subsetexplorermap.get(title); } if (team != null) { RBDVal rbdv = rres.get(team); if (rbdv == null) rres.put(team, new RBDVal(team)); else rbdv.c++; } } } } List vres = new ArrayList(rres.values()); Collections.sort(vres); List sres = new ArrayList(); for (RBDVal v : vres) sres.add(v.s + " (" + v.c + ")\n"); return sres; } ///////////////////////////////////////////// // works by looking for the most complex submapping boolean FindPrimaryFrame(OneSketch asketch) { // find the primary frame and its subset mapping int nsubsetscomp = 0; assert osaframe == null; for (OneSArea osa : asketch.vsareas) { // should also make sure of pframesketch is not null (not of an image) if (osa.iareapressig != SketchLineStyle.ASE_SKETCHFRAME) continue; if (osa.opsketchframedefs.isEmpty()) continue; // the sketch frame def is the one with more than one image in it (so we can distinguish between icons) if ((osa.opsketchframedefs.size() > 1) && osa.opsketchframedefs.get(0).plabedl.sketchframedef.IsImageType()) { osaframepicture = osa; continue; } // find the frame with the most subsets in all its sketches // the target subsets (colours) are common across all brought in sketches Set Ssubsets = new HashSet(); for (OnePath lop : osa.opsketchframedefs) Ssubsets.addAll(lop.plabedl.sketchframedef.submapping.values()); if ((osaframe == null) || (nsubsetscomp < Ssubsets.size())) { osaframe = osa; nsubsetscomp = Ssubsets.size(); } // the frame which has strongrey is the border frame if ((Ssubsets.size() == 1) && Ssubsets.contains("strongrey")) osaframeborder = osa; // the thumbnail sketch is the one with the greatest scaledown if ((osaframethumb == null) || (osa.opsketchframedefs.get(0).plabedl.sketchframedef.sfscaledown > thumbframescaledown)) { osaframethumb = osa; thumbframescaledown = osaframethumb.opsketchframedefs.get(0).plabedl.sketchframedef.sfscaledown; } } if (osaframe == null) return false; framescaledown = -1.0F; if (osaframeborder == osaframe) osaframeborder = null; if (osaframeborder != null) System.out.println("***** borderframe detected"); for (OnePath op : asketch.vpaths) { if (op.IsSketchFrameConnective()) { if ((op.kaleft == osaframe) || (op.karight == osaframe)) { opsframeslaP.add(op); // for indexOf TN.emitMessage("opsframeslaP.add "+op); opsframesla.add(new TSketchLevelArea(op)); if (framescaledown == -1.0) framescaledown = op.plabedl.sketchframedef.sfscaledown; else assert op.plabedl.sketchframedef.sfscaledown == framescaledown; } if ((osaframeborder != null) && ((op.kaleft == osaframeborder) || (op.karight == osaframeborder))) { TN.emitMessage("opsframeborder.add "+op); opsframeborder.add(op); } } } System.out.println("Primary frame scale " + framescaledown + " opsframeslaP:" + opsframeslaP.size()); // make sure the order of the border sketches is the same so we can used them as such // (in future could reorder them but too much hassle and only happens once) if (!opsframeborder.isEmpty()) { assert opsframeborder.size() == opsframesla.size(); for (int i = 0; i < opsframesla.size(); i++) { assert opsframeborder.get(i).plabedl.sketchframedef.sfsketch.equals(opsframesla.get(i).sketchframedef.sfsketch); System.out.println("SSSScaledown " + opsframeborder.get(i).plabedl.sketchframedef.sfscaledown); assert opsframeborder.get(i).plabedl.sketchframedef.sfscaledown == framescaledown; } } if ((osaframethumb != null) && ((osaframethumb == osaframe) || (osaframethumb == osaframeborder))) osaframethumb = null; if (osaframethumb != null) System.out.println("***** thumbframe detected"); return true; } ///////////////////////////////////////////// void MakeFrameSubmapping(OneSketch asketch) { for (int i = 0; i < opsframesla.size(); i++) { TSketchLevelArea sla = opsframesla.get(i); if ((sla.sketchframedef == null) || (sla.sketchframedef.pframesketchtrans == null)) TN.emitError("You need to update and load the sketches in the atlas template sketch first"); // transform is the same, until it accounts for the LocOffset try { sla.pframesketchtransinverse = sla.sketchframedef.pframesketchtrans.createInverse(); } catch (NoninvertibleTransformException e) {;} assert sla.sketchframedef.sfscaledown == opsframesla.get(0).sketchframedef.sfscaledown; assert sla.sketchframedef.sfxtrans == opsframesla.get(0).sketchframedef.sfxtrans; assert sla.sketchframedef.sfytrans == opsframesla.get(0).sketchframedef.sfytrans; assert sla.sketchframedef.sfrotatedeg == opsframesla.get(0).sketchframedef.sfrotatedeg; for (Map.Entry esubset : sla.sketchframedef.submapping.entrySet()) { TSublevelmapping tsl = subcolmap.get(esubset.getValue()); if (tsl == null) { tsl = new TSublevelmapping(esubset.getValue(), opsframesla.size()); subcolmap.put(esubset.getValue(), tsl); } tsl.slm.get(i).subsets.add(esubset.getKey()); } } } ///////////////////////////////////////////// List FileIntoSublevelmapping(Area aareatranslate) { for (TSublevelmapping tsl : subcolmap.values()) tsl.clear(); for (int i = 0; i < opsframesla.size(); i++) { TSketchLevelArea tsla = opsframesla.get(i); for (OnePath op : tsla.pathspresent) { for (String subset : op.vssubsets) { String subcol = tsla.sketchframedef.submapping.get(subset); if (subcol != null) { TSublevelmapping tsl = subcolmap.get(subcol); double dx = op.pnend.pn.getX() - op.pnstart.pn.getX(); double dy = op.pnend.pn.getY() - op.pnstart.pn.getY(); double lzweight = Math.sqrt(dx * dx + dy * dy); double lzavg = (op.pnend.zalt + op.pnstart.zalt) / 2; if (op.linestyle != SketchLineStyle.SLS_CONNECTIVE) { tsl.zsum += lzavg * lzweight; tsl.zweight += lzweight; float lzlo = Math.min(op.pnstart.zalt, op.pnend.zalt) / TN.CENTRELINE_MAGNIFICATION + tsla.fsketch.sketchLocOffset.z; float lzhi = Math.max(op.pnstart.zalt, op.pnend.zalt) / TN.CENTRELINE_MAGNIFICATION + tsla.fsketch.sketchLocOffset.z; if ((tsl.npaths == 0) || (lzlo < tsl.zlo)) tsl.zlo = lzlo; if ((tsl.npaths == 0) || (lzhi > tsl.zhi)) tsl.zhi = lzhi; tsl.npaths++; } } } } for (OneSArea osa : tsla.areaspresent) { String subset = tsla.FindCommonSubsetA(osa); if (subset != null) { String subcol = tsla.sketchframedef.submapping.get(subset); if (subcol != null) { TSublevelmapping tsl = subcolmap.get(subcol); tsl.slm.get(i).vsareas.add(osa); tsl.slm.get(i).uarea.add(osa.aarea); // absorb the range for the area //tsl.AbsorbRangeZ(op.pnstart.zalt); //tsl.AbsorbRangeZ(op.pnend.zalt); } } } } // find the levels that actually have any elements List res = new ArrayList(); for (TSublevelmapping tsl : subcolmap.values()) { if (tsl.npaths != 0) { res.add(tsl); System.out.println(tsl.Drep()); assert tsl.slm.size() == opsframesla.size(); for (int i = 0; i < opsframesla.size(); i++) { TSublevelmappingL sl = tsl.slm.get(i); TSketchLevelArea tsla = opsframesla.get(i); tsl.uareaA.add(sl.uarea.createTransformedArea(tsla.sketchframedef.pframesketchtrans)); } tsl.uareaA.intersect(aareatranslate); } } Collections.sort(res); return res; } // improve the z-ordering estimation // v important // improve overlap estimation to handle simple adjoining of levels // trawl through survey data to find which teams and dates when // selected sections were surveyed // this will be done by looking through all centrelines present in the sketch and // listing all mappings in subsetexplorermap that go from their title set subsets // (which can be assembled from the visible) and substituting the text into // label of type: titlesurveyors // this is working for entire tile rather than layer in tile // trawl through photo library which will be tagged with same subsets // that are active so we can allocate them automatically, avoiding duplicates // handle the minimap which will be at a // different scale and needs to avoid being offset by 125m and have separate zones // when we run over. ///////////////////////////////////////////// static float acoords[] = new float[6]; static float MeasureAreaofArea(Area area, float flatness) { float res2 = 0.0F; PathIterator pi = area.getPathIterator(null, flatness); float xl = 0.0F; float yl = 0.0F; while (!pi.isDone()) { int pic = pi.currentSegment(acoords); if (pic == PathIterator.SEG_LINETO) res2 += xl * acoords[1] - yl * acoords[0]; //if (pic == PathIterator.SEG_CLOSE) // check if there's a difference in endpoint //if (pic == PathIterator.SEG_MOVETO) xl = acoords[0]; yl = acoords[1]; pi.next(); } return Math.abs(res2) / 2; } ///////////////////////////////////////////// boolean CopySketchDisplacedLayer(float xdisp, float ydisp, String newcommonsubset, OneSketch asketch, List sexplorers, float zlo, float zhi, int ipic) { Map opnmap = new HashMap(); for (OnePathNode opn : asketch.vnodes) opnmap.put(opn, new OnePathNode((float)opn.pn.getX() + xdisp, (float)opn.pn.getY() + ydisp, opn.zalt)); // cycle through the pictures if (osaframepicture != null) { ipic = ipic % osaframepicture.opsketchframedefs.size(); if (sexplorers.size() >= 10) ipic = -2; while (sexplorers.size() > 19) sexplorers.remove(sexplorers.size() - 1); } System.out.println("ipioioioippipip " + ipic); for (OnePath op : asketch.vpaths) { float[] pco = op.GetCoords(); OnePath lop; // thumbnail displacement case if ((op.pnstart == op.pnend) && (op.pnstart.pathcount == 2) && op.vssubsets.contains("shaded") && (osaframethumb != null)) { float xdth = xdisp * framescaledown / thumbframescaledown; float ydth = ydisp * framescaledown / thumbframescaledown; OnePathNode opnth = new OnePathNode((float)op.pnstart.pn.getX() + xdisp + xdth, (float)op.pnend.pn.getY() + ydisp + ydth, op.pnstart.zalt); lop = new OnePath(opnth); for (int i = 1; i < op.nlines; i++) lop.LineTo(pco[i * 2 + 0] + xdisp + xdth, pco[i * 2 + 1] + ydisp + ydth); lop.EndPath(opnth); } // normal case else { lop = new OnePath(opnmap.get(op.pnstart)); for (int i = 1; i < op.nlines; i++) lop.LineTo(pco[i * 2 + 0] + xdisp, pco[i * 2 + 1] + ydisp); lop.EndPath(opnmap.get(op.pnend)); } lop.CopyPathAttributes(op); lop.vssubsets.remove(commonsubset); lop.vssubsets.add(newcommonsubset); if (lop.bWantSplined && !OnePath.bHideSplines) lop.Spline(lop.bWantSplined, false); // limit down the subset mapping if (op.IsSketchFrameConnective()) { // primary frame if ((op.kaleft == osaframe) || (op.karight == osaframe)) { int i = opsframeslaP.indexOf(op); TN.emitMessage("opsframeslaP.indexOf "+op+" "+i); assert i >= 0; TSketchLevelArea sla = opsframesla.get(i); // remove and change the values in here Map submapping = lop.plabedl.sketchframedef.submapping; Set subsets = new HashSet(submapping.keySet()); for (String subset : subsets) { if (sla.brightgreysubsets.contains(subset)) submapping.put(subset, "brightgrey"); else if (sla.greyedsubsets.contains(subset)) submapping.put(subset, "greyed"); else if (!sla.retainsubsets.contains(subset)) submapping.remove(subset); } submapping.put("default", "obscuredsets"); } else if ((osaframeborder != null) && ((op.kaleft == osaframeborder) || (op.karight == osaframeborder))) { Map submapping = lop.plabedl.sketchframedef.submapping; submapping.clear(); int i = opsframeborder.indexOf(op); TN.emitMessage("opsframeborder.indexOf "+op+" "+i); assert i >= 0; TSketchLevelArea sla = opsframesla.get(i); for (String subset : sla.sketchframedef.submapping.keySet()) { if (sla.greyedsubsets.contains(subset)) submapping.put(subset, "greyed"); else if (sla.retainsubsets.contains(subset)) submapping.put(subset, "strongrey"); } submapping.put("default", "obscuredsets"); } // keep the position on the map steady (unless we are to shift an entire chunk over!) else if ((op.kaleft == osaframethumb) || (op.karight == osaframethumb)) { lop.plabedl.sketchframedef.sfxtrans += xdisp / 1000.0F / TN.CENTRELINE_MAGNIFICATION; lop.plabedl.sketchframedef.sfytrans += ydisp / 1000.0F / TN.CENTRELINE_MAGNIFICATION; } // move the images along with the frame else if (lop.plabedl.sketchframedef.IsImageType()) { lop.plabedl.sketchframedef.sfxtrans += xdisp / TN.CENTRELINE_MAGNIFICATION; lop.plabedl.sketchframedef.sfytrans += ydisp / TN.CENTRELINE_MAGNIFICATION; // drop all pictures except one if ((osaframepicture != null) && ((op.kaleft == osaframepicture) || (op.karight == osaframepicture))) { int lipic = osaframepicture.opsketchframedefs.indexOf(op); if (ipic != lipic) lop = null; } } } // set the explorer names else if ((lop.linestyle == SketchLineStyle.SLS_CONNECTIVE) && (lop.plabedl != null) && !lop.plabedl.sfontcode.equals("")) { if (lop.plabedl.drawlab.equalsIgnoreCase("*explorers*")) { StringBuffer sb = new StringBuffer(); for (String sexplorer : sexplorers) sb.append(sexplorer); lop.plabedl.drawlab = sb.toString(); } else if (lop.plabedl.drawlab.equalsIgnoreCase("*tilenumber*")) lop.plabedl.drawlab = "Tile: " + newcommonsubset; else if (lop.plabedl.drawlab.startsWith("*lat*")) { float lat = Float.parseFloat(lop.plabedl.drawlab.substring(5).trim()); float tlat = lat - ((ydisp / TN.CENTRELINE_MAGNIFICATION) / 1000.0F) * framescaledown; lop.plabedl.drawlab = String.format("%.3f", tlat); } else if (lop.plabedl.drawlab.startsWith("*lon*")) { float lon = Float.parseFloat(lop.plabedl.drawlab.substring(5).trim()); float tlon = lon + ((xdisp / TN.CENTRELINE_MAGNIFICATION) / 1000.0F) * framescaledown; lop.plabedl.drawlab = String.format("%.3f", tlon); } else if (lop.plabedl.drawlab.startsWith("*depth*")) { lop.plabedl.drawlab = String.format("Z %d to %d", (int)zlo, (int)zhi); } else if (lop.plabedl.drawlab.equalsIgnoreCase("*tilenumber*")) lop.plabedl.drawlab = "Tile: " + newcommonsubset; } // kill off entire picture frame if it's being cut off else if ((ipic == -2) && ((op.kaleft == osaframepicture) || (op.karight == osaframepicture))) lop = null; if (lop != null) vpathsatlas.add(lop); } return (ipic >= 0); } static String alphabet = "abcdefghijklmnopqerstuvwxyz"; ///////////////////////////////////////////// int CopySketchDisplaced(float xdisp, float ydisp, String newcommonsubset, OneSketch asketch) { // translate the framed area and then transform into real space (the space of the paths of asketch) Area aareatranslate = osaframe.aarea.createTransformedArea(AffineTransform.getTranslateInstance(xdisp, ydisp)); // discover the paths and subsets in the framed sketch boolean bpathspresent = false; for (int i = 0; i < opsframesla.size(); i++) { TSketchLevelArea sla = opsframesla.get(i); sla.areaframeRS = aareatranslate.createTransformedArea(sla.pframesketchtransinverse); sla.rectframeRS = sla.areaframeRS.getBounds2D(); sla.rectframeRSA = new Area(sla.rectframeRS); sla.FindAreasPathsPresent(); if (!sla.pathspresent.isEmpty()) bpathspresent = true; } if (!bpathspresent) return 0; //TN.emitMessage(" Skipping this atlas page"); TN.emitMessage("Gnerating::: " + newcommonsubset); List tsllist = FileIntoSublevelmapping(aareatranslate); for (int j = 0; j < tsllist.size(); j++) tsllist.get(j).FindAdjoiningSubsets((j != 0 ? tsllist.get(j - 1) : null), (j < tsllist.size() - 1 ? tsllist.get(j + 1) : null), opsframesla); System.out.println("tttt " + tsllist.size()); if (tsllist.size() == 0) CopySketchDisplacedLayer(xdisp, ydisp, newcommonsubset, asketch, new ArrayList(), 0.0F, 1.0F, Sipic); int ljc = 0; // level count int j = 0; while (j < tsllist.size()) { float zlo = tsllist.get(j).zlo; float zhi = tsllist.get(j).zhi; for (int i = 0; i < opsframesla.size(); i++) { TSketchLevelArea sla = opsframesla.get(i); sla.retainsubsets.clear(); sla.greyedsubsets.clear(); sla.brightgreysubsets.clear(); sla.retainsubsets.addAll(tsllist.get(j).slm.get(i).subsets); } // find if we can collapse with next level down int j1 = j + 1; while (j1 < tsllist.size()) { Area larea = new Area(tsllist.get(j).uareaA); for (int lj = j + 1; lj < j1; lj++) larea.add(tsllist.get(lj).uareaA); System.out.print("AArea " + MeasureAreaofArea(larea, 0.1F) + " "); // intersecting collapsed levels -- must check if it's just on the border part, because otherwise too sensitive larea.intersect(tsllist.get(j1).uareaA); System.out.println("IArea " + MeasureAreaofArea(larea, 0.1F)); if (!larea.isEmpty()) break; System.out.println("collapsinglevels " + j + " " + j1); for (int i = 0; i < opsframesla.size(); i++) { TSketchLevelArea sla = opsframesla.get(i); sla.retainsubsets.addAll(tsllist.get(j1).slm.get(i).subsets); } if (tsllist.get(j1).zlo < zlo) zlo = tsllist.get(j1).zlo; if (tsllist.get(j1).zhi > zhi) zhi = tsllist.get(j1).zhi; j1++; } for (int k = j1; k < tsllist.size(); k++) { for (int i = 0; i < opsframesla.size(); i++) { TSketchLevelArea sla = opsframesla.get(i); sla.greyedsubsets.addAll(tsllist.get(k).slm.get(i).subsets); } } if (j1 < tsllist.size()) { for (int i = 0; i < opsframesla.size(); i++) { TSketchLevelArea sla = opsframesla.get(i); sla.brightgreysubsets.addAll(tsllist.get(j1 - 1).slm.get(i).adjoiningsubsetsbelow); } } for (int i = 0; i < opsframesla.size(); i++) { TSketchLevelArea sla = opsframesla.get(i); sla.brightgreysubsets.addAll(tsllist.get(j).slm.get(i).adjoiningsubsetsabove); } List sexplorers = FindExplorers(); String lnewcommonsubset = newcommonsubset + "_" + alphabet.substring(ljc, ljc + 1); boolean bpicused = CopySketchDisplacedLayer(xdisp, ydisp, lnewcommonsubset, asketch, sexplorers, zlo, zhi, Sipic); ljc++; j = j1; if (bpicused) Sipic++; } return ljc; } static int Sipic = 0; ///////////////////////////////////////////// // take the sketch from the displayed window and import it from the selected sketch in the mainbox. boolean ImportAtlasTemplate(OneSketch asketch) { commonsubset = FindCommonSubset(asketch); // for the whole image if (commonsubset == null) return TN.emitWarning("No common subset in the template sketch to use as the basis: " + asketch.sketchfile.getPath()); System.out.println("commonsubset: " + commonsubset + " nareas " + asketch.vsareas.size()); if (!FindPrimaryFrame(asketch)) return TN.emitWarning("Primary frame failure"); MakeFrameSubmapping(asketch); for (int i = 0; i < opsframesla.size(); i++) opsframesla.get(i).SetExplorerMap(); Sipic = 0; // will need to scan for the boundaries of the entire diagram // hard coded the width of the window at 50units until size of the primary frame is handled properly for (int it = 0; it <= 10; it++) for (int jt = 0; jt <= 22; jt++) //for (int it = 5; it <= 6; it++) //for (int jt = 3; jt <= 4; jt++) { float xdisp = (it - 5) * 50.0F * TN.CENTRELINE_MAGNIFICATION; float ydisp = (jt - 7) * 50.0F * TN.CENTRELINE_MAGNIFICATION; String newcommonsubset = "page_" + it + "_" + jt; int dipic = CopySketchDisplaced(xdisp, ydisp, newcommonsubset, asketch); } return true; } } tunnelx-20140102.orig/src/InstantHelp.java0000644000000000000000000001170211762432750015162 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import javax.swing.JWindow; import javax.swing.JFrame; import javax.swing.JTextPane; import javax.swing.JEditorPane; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JComboBox; import javax.swing.JScrollPane; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.Point; import java.awt.Dimension; import java.awt.BorderLayout; import java.awt.Font; import java.awt.Color; import java.util.List; import java.util.ArrayList; ///////////////////////////////////////////// class InstantHelp extends JFrame // JWindow { MainBox mainbox; JPanel hpanel = new JPanel(new BorderLayout()); //JTextPane textpane = new JTextPane(); JEditorPane textpane = new JEditorPane(); JComboBox selectbox = new JComboBox(); List mihelpsmain = new ArrayList(); List mihelps = new ArrayList(); List helptitles = new ArrayList(); List helptexts = new ArrayList(); boolean bfirst = true; ///////////////////////////////////////////// void ShowHelp(int i, boolean bmainhelp) { if (bfirst) { Point loc = (!bmainhelp ? mainbox.sketchdisplay.getLocation() : mainbox.getLocation()); Dimension dim = (!bmainhelp ? mainbox.sketchdisplay.getSize() : mainbox.getSize()); setLocation((int)loc.getX() + dim.width / 3, (int)loc.getY() + dim.height / 3); setSize((int)(dim.width * 0.6), (int)(dim.height * 0.7)); bfirst = false; } setVisible(true); selectbox.setSelectedIndex(i); } ///////////////////////////////////////////// class MItemSelect extends JMenuItem { boolean bmainhelp; int selectindex; MItemSelect(String helptitle, int lselectindex) { bmainhelp = helptitle.startsWith("Main - "); setText(bmainhelp ? helptitle.substring(7) : helptitle); selectindex = lselectindex; addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { ShowHelp(selectindex, bmainhelp); } } ); } } ///////////////////////////////////////////// InstantHelp(MainBox lmainbox) { //super(lsketchdisplay); // if doing this by a JWindow mainbox = lmainbox; selectbox.setFont(new Font("Arial", Font.BOLD, 22)); selectbox.setBackground(Color.white); String lhelptext = FileAbstraction.helpFile.ReadFileHeadLB(-1); int ih1 = lhelptext.indexOf("

"); while (ih1 != -1) { int ih1e = lhelptext.indexOf("

", ih1); String helptitle = lhelptext.substring(ih1 + 4, ih1e).trim(); int ih1n = lhelptext.indexOf("

", ih1e); //String helptext = (ih1n != -1 ? lhelptext.substring(ih1, ih1n) : lhelptext.substring(ih1)).trim(); String helptext = (ih1n != -1 ? lhelptext.substring(ih1e + 5, ih1n) : lhelptext.substring(ih1e + 5)).trim(); ih1 = ih1n; MItemSelect mihelp = new MItemSelect(helptitle, helptexts.size()); helptitles.add(helptitle); helptexts.add(helptext); if (mihelp.bmainhelp) mihelpsmain.add(mihelp); else mihelps.add(mihelp); selectbox.addItem(helptitle); } textpane.setContentType("text/html"); textpane.setEditable(false); setAlwaysOnTop(true); hpanel.add(selectbox, BorderLayout.NORTH); hpanel.add(new JScrollPane(textpane), BorderLayout.CENTER); selectbox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { int i = selectbox.getSelectedIndex(); textpane.setText(helptexts.get(i)); textpane.setCaretPosition(0); textpane.grabFocus(); }}); add(hpanel); setSize(200, 100); pack(); } } tunnelx-20140102.orig/src/SSymbScratchPath.java0000644000000000000000000000513311762432750016114 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2007 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.geom.Point2D; ///////////////////////////////////////////// class SSymbScratchPath { double[] cumpathleng = new double[256]; // (nodelength, reallength) records the distance to each node along the path, as pairs int lencumpathleng = -1; Point2D pathevalpoint = new Point2D.Double(); Point2D pathevaltang = new Point2D.Double(); ///////////////////////////////////////////// void SetUpPathLength(OnePath lpath) { lpath.GetCoords(); lencumpathleng = 0; int nsegs = (lpath.bSplined ? 5 : 1); double clen = 0.0; double prevx = 0.0; double prevy = 0.0; for (int i = 0; i < lpath.nlines; i++) { for (int j = (i == 0 ? 0 : 1); j <= nsegs; j++) { double tr = (double)j / nsegs; lpath.EvalSeg(pathevalpoint, null, i, tr); if ((i != 0) || (j != 0)) { double vx = pathevalpoint.getX() - prevx; double vy = pathevalpoint.getY() - prevy; clen += Math.sqrt(vx * vx + vy * vy); } cumpathleng[lencumpathleng * 2] = i + tr; cumpathleng[lencumpathleng * 2 + 1] = clen; prevx = pathevalpoint.getX(); prevy = pathevalpoint.getY(); lencumpathleng++; } } } ///////////////////////////////////////////// double ConvertAbstoNodePathLength(double r, OnePath lpath) { int i; for (i = 1; i < lencumpathleng; i++) { if (r <= cumpathleng[i * 2 + 1]) { double lam = (r - cumpathleng[i * 2 - 1]) / (cumpathleng[i * 2 + 1] - cumpathleng[i * 2 - 1]); return cumpathleng[i * 2 - 2] * (1.0 - lam) + cumpathleng[i * 2] * lam; } } return 0.0; } ///////////////////////////////////////////// double GetCumuPathLength() { return cumpathleng[lencumpathleng * 2 - 1]; } }; tunnelx-20140102.orig/src/TunnelXML.javawithjaxp0000644000000000000000000000613611762432750016343 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.io.File; import java.io.IOException; import org.xml.sax.*; import javax.xml.parsers.SAXParserFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; ///////////////////////////////////////////// // local class of the parser. class TunnelXML extends HandlerBase // DefaultHandler { SAXParserFactory factory; TunnelXMLparse txp; ///////////////////////////////////////////// void emitError(String mess, IOException e) throws IOException { TN.emitError(mess); throw e; } ///////////////////////////////////////////// TunnelXML() { factory = SAXParserFactory.newInstance(); } ///////////////////////////////////////////// void ParseFile(TunnelXMLparse ltxp, File sfile) { try { txp = ltxp; SAXParser saxParser = factory.newSAXParser(); saxParser.parse(sfile, this); } catch (SAXException e) { System.out.println(e.toString()); e.printStackTrace(); } catch (ParserConfigurationException e) { System.out.println(e.toString()); e.printStackTrace(); } catch (IOException e) { System.out.println(e.toString()); e.printStackTrace(); } } ///////////////////////////////////////////// public void startElement(String name, AttributeList attrs) throws SAXException { // roll forward the stack and introduce the attributes txp.iposstack[txp.istack] = (txp.istack == 0 ? 0 : txp.iposstack[txp.istack - 1]); txp.elemstack[txp.istack] = name; for (int i = 0; i < attrs.getLength(); i++) { txp.attnamestack[txp.iposstack[txp.istack]] = attrs.getName(i); txp.attvalstack[txp.iposstack[txp.istack]] = attrs.getValue(i); txp.iposstack[txp.istack]++; } txp.istack++; txp.startElementAttributesHandled(name); } ///////////////////////////////////////////// public void characters(char[] ch, int start, int length) throws SAXException { txp.characters(null, ch, start, length); } ///////////////////////////////////////////// public void endElement(String name) throws SAXException { // roll back the stack txp.istack--; txp.endElementAttributesHandled(name); } }; tunnelx-20140102.orig/src/LabelFontAttr.java0000644000000000000000000000667112261213471015433 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2007 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.BasicStroke; import java.awt.Font; import java.awt.Color; ///////////////////////////////////////////// class LabelFontAttr { SubsetAttr subsetattr; // backpointer String labelfontname; // defining parameters String sfontsize = null; String sfontname = null; String sfontstyle = null; float ffontsize = -1.0F; String fontname = null; String fontstyle = null; Font fontlab = null; // filled automatically String slabelcolour = null; // none means we draw nothing for this font. Color labelcolour = null; // none means we draw nothing for this font. BasicStroke labelstroke = null; ///////////////////////////////////////////// LabelFontAttr(String llabelfontname, SubsetAttr lsubsetattr) { labelfontname = llabelfontname; subsetattr = lsubsetattr; } ///////////////////////////////////////////// // copy of whole style LabelFontAttr(LabelFontAttr lfa, SubsetAttr lsubsetattr) { labelfontname = lfa.labelfontname; sfontname = lfa.sfontname; sfontstyle = lfa.sfontstyle; sfontsize = lfa.sfontsize; slabelcolour = lfa.slabelcolour; subsetattr = lsubsetattr; } ///////////////////////////////////////////// LabelFontAttr(Color color, Font font) { labelcolour = color; fontlab = font; subsetattr = null; } ///////////////////////////////////////////// void FillMissingAttribsLFA(LabelFontAttr lfaupper) { assert (lfaupper == null) || labelfontname.equals(lfaupper.labelfontname); // should be copying over from same named style if ((lfaupper != null) && (slabelcolour == null)) slabelcolour = lfaupper.slabelcolour; labelcolour = SubsetAttr.ConvertColour(subsetattr.EvalVars(slabelcolour), Color.gray); if ((lfaupper != null) && (sfontname == null)) sfontname = lfaupper.sfontname; if ((lfaupper != null) && (sfontsize == null)) sfontsize = lfaupper.sfontsize; if ((lfaupper != null) && (sfontstyle == null)) sfontstyle = lfaupper.sfontstyle; fontname = SubsetAttr.ConvertString(subsetattr.EvalVars(sfontname), "Serif"); ffontsize = SubsetAttr.ConvertFloat(subsetattr.EvalVars(sfontsize), 10.0F); fontstyle = SubsetAttr.ConvertString(subsetattr.EvalVars(sfontstyle), "PLAIN"); int ifontstyle = (fontstyle.equals("ITALIC") ? Font.ITALIC : (fontstyle.equals("BOLD") ? Font.BOLD : Font.PLAIN)); fontlab = new Font(fontname, ifontstyle, (int)(ffontsize + 0.5F)); float labstrokewidth = ffontsize * 0.08F; labelstroke = new BasicStroke(labstrokewidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, labstrokewidth * 5); } }; tunnelx-20140102.orig/src/NetConnection.java0000644000000000000000000003602011762432750015477 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2011 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.util.List; import java.util.ArrayList; import java.io.InputStream; import java.io.InputStreamReader; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; import java.awt.Image; import java.awt.image.BufferedImage; import javax.imageio.ImageIO; import java.net.URLClassLoader; import java.net.URL; import java.net.URLConnection; import java.net.MalformedURLException; import java.net.ConnectException; import java.util.Collections; ///////////////////////////////////////////// class PthChange { String uuid; String action; String val = ""; String sketchuuid; PthChange(OnePath op, String laction, String lsketchuuid) { uuid = op.uuid; action = laction; sketchuuid = lsketchuuid; if (action.equals("add")) { LineOutputStream los = new LineOutputStream(); try { op.WriteXMLpath(los, -1, -1, 0); } catch (IOException ie) {;} val = los.sb.toString(); } } } //////////////////////////////////////////////////////////////////////////////// class NetConnection implements Runnable { URL urlnetconnection = null; Thread ncthread = null; List pthchanges = Collections.synchronizedList(new ArrayList()); MainBox mainbox; NetConnection(MainBox lmainbox) { mainbox = lmainbox; } ///////////////////////////////////////////// public void run() { try { while (true) { Thread.sleep(500); if (!pthchanges.isEmpty()) PostPathChangeBatch(); } } catch (InterruptedException ie) {;} ncthread = null; } ///////////////////////////////////////////// void PostPathChangeBatch() { List args = new ArrayList(); int ipthchanges = 0; String lsketchuuid = null; for ( ; ipthchanges < 10; ipthchanges++) { if (ipthchanges >= pthchanges.size()) break; if (ipthchanges == 0) lsketchuuid = pthchanges.get(ipthchanges).sketchuuid; else if (!pthchanges.get(ipthchanges).sketchuuid.equals(lsketchuuid)) break; PthChange pthchange = pthchanges.get(ipthchanges); args.add("uuid_"+ipthchanges); args.add(pthchange.uuid); args.add("action_"+ipthchanges); args.add(pthchange.action); args.add("val_"+ipthchanges); args.add(pthchange.val); } if (ipthchanges == 0) return; args.add("npthchanges"); args.add(String.valueOf(ipthchanges)); args.add("sketchuuid"); args.add(lsketchuuid); try { String res = SimplePost(urlnetconnection, args); System.out.println(res); } catch (ConnectException ce) { TN.emitWarning("Connection refused, turning off"); mainbox.miNetConnection.setState(false); return; } catch (IOException ie) { System.out.println(ie); } while (ipthchanges > 0) pthchanges.remove(--ipthchanges); } ///////////////////////////////////////////// void netcommitpathchange(OnePath op, String action, OneSketch tsketch) { if (mainbox.miNetConnection.getState()) pthchanges.add(new PthChange(op, action, tsketch.sketchfile.getPath())); } ///////////////////////////////////////////// void ncstart(String snetconnection) { try { urlnetconnection = new URL(snetconnection); } catch (MalformedURLException e) { TN.emitWarning("yyy"); return; } ncthread = new Thread(this); ncthread.start(); mainbox.miNetConnection.setState(true); try { List args = new ArrayList(); args.add("connectionmade"); args.add(TN.tunnelversion); String d = SimplePost(urlnetconnection, args); System.out.println("Response:"+d); } catch (ConnectException ce) { TN.emitWarning("Connection refused, turning off"); mainbox.miNetConnection.setState(false); } catch (IOException ie) {;} } ///////////////////////////////////////////// ///////////////////////////////////////////// static String boundry = "-----xxxxxxxBOUNDERxxxxdsx"; // something that is unlikely to appear in the text public static void writeField(DataOutputStream out, String name, String value) throws java.io.IOException { out.writeBytes("--"); out.writeBytes(boundry); out.writeBytes("\r\n"); out.writeBytes("Content-Disposition: form-data; name=\"" + name + "\""); out.writeBytes("\r\n"); out.writeBytes("\r\n"); out.writeBytes(value); out.writeBytes("\r\n"); out.flush(); //TN.emitMessage("WriteField: " + name + "=" + value); } ///////////////////////////////////////////// static void writeTileImageFile(DataOutputStream out, String fieldname, String filename, BufferedImage bi) throws java.io.IOException { out.writeBytes("--"); out.writeBytes(boundry); out.writeBytes("\r\n"); out.writeBytes("Content-Disposition: form-data; name=\"" + fieldname + "\"; filename=\"" + filename + "\""); out.writeBytes("\r\n"); out.writeBytes("Content-Type: image/png"); out.writeBytes("\r\n"); out.writeBytes("\r\n"); ImageIO.write(bi, "png", out); out.writeBytes("\r\n"); } ///////////////////////////////////////////// static void writeSketchFile(DataOutputStream out, String name, String fileName, OneSketch tsketch) throws java.io.IOException { out.writeBytes("--"); out.writeBytes(boundry); out.writeBytes("\r\n"); out.writeBytes("Content-Disposition: form-data; name=\"" + name + "\"; filename=\"" + fileName + "\""); out.writeBytes("\r\n"); out.writeBytes("Content-Type: text/plain"); out.writeBytes("\r\n"); out.writeBytes("\r\n"); LineOutputStream los = new LineOutputStream(out); tsketch.SaveSketchLos(los); out.writeBytes("\r\n"); } ///////////////////////////////////////////// ///////////////////////////////////////////// // returns the URL of the image that has been uploaded // should be a member function public static FileAbstraction uploadFile(FileAbstraction target, String fieldname, String filename, BufferedImage bi, OneSketch tsketch) { String fres = ""; try { assert target.localurl != null; String response = ""; URL url = target.localurl; // append a command onto the end of the url to say what we're doing if (url.toString().endsWith(".xml")) url = new URL(url.toString() + "/upload"); TN.emitMessage("About to post\nURL: " + url.toString()); URLConnection conn = url.openConnection(); // Set connection parameters. conn.setDoInput(true); conn.setDoOutput(true); conn.setUseCaches(false); // Make server believe we are form data conn.setRequestProperty("Content-Type", "multipart/related; boundary=" + boundry); // connection.setRequestProperty("MIME-version", "1.0"); DataOutputStream out = new DataOutputStream (conn.getOutputStream()); // out.write(("--" + boundry + " ").getBytes()); // write some fields writeField(out, "tunneluser", TN.tunneluser); writeField(out, "tunnelpassword", TN.tunnelpassword); writeField(out, "tunnelproject", TN.tunnelproject); writeField(out, "tunnelversion", TN.tunnelversion); // Write out the bytes of the content string to the stream. assert ((bi == null) != (tsketch == null)); if (bi != null) writeTileImageFile(out, fieldname, filename, bi); else writeSketchFile(out, fieldname, filename, tsketch); out.writeBytes("--"); out.writeBytes(boundry); out.writeBytes("--"); out.writeBytes("\r\n"); out.flush(); out.close(); // Read response from the input stream (should detect the file name). // directly from fileupload.html in the django template String suploadedfile = "
  • UPLOADEDFILE: "; String smessage = "

    MESSAGE: "; //Pattern pattuploadedfile = Pattern.compile("

  • UPLOADEDFILE: \"(.*?)\"
  • "); //Pattern pattmessage = Pattern.compile("

    MESSAGE: (.*?)"); BufferedReader fin = new BufferedReader(new InputStreamReader(conn.getInputStream ())); String fline; System.out.println("Server response:"); while ((fline = fin.readLine()) != null) { System.out.println(":" + fline); int iuploadedfile = fline.indexOf(suploadedfile); if (iuploadedfile != -1) { fres = fline.substring(iuploadedfile + suploadedfile.length()); System.out.println("FIFIF:" + fres + ":::"); } } fin.close(); } catch (MalformedURLException e) { TN.emitWarning("yyy"); return null;} catch (IOException e) { TN.emitWarning("eee " + e.toString()); return null;} return FileAbstraction.MakeOpenableFileAbstraction(fres); } ///////////////////////////////////////////// // see: http://seagrass.goatchurch.org.uk/~mjg/cgi-bin/addsurvey.py // // // // public static void upmjgirebyoverlay(BufferedImage bi, String name, double dpmetrereal, double cornercoordX, double cornercoordY, String spatial_reference_system) { try { String target = "http://seagrass.goatchurch.org.uk/caves/image/upload_and_locate_image"; TN.emitMessage("About to post\nURL: " + target); System.out.println(" fname=" + name + " ----dots per metre " + dpmetrereal + " XX " + cornercoordX + " YY " + cornercoordY + " spatial_system " + spatial_reference_system); String response = ""; URL url = new URL(target); URLConnection conn = url.openConnection(); // Set connection parameters. conn.setDoInput(true); conn.setDoOutput(true); conn.setUseCaches(false); // Make server believe we are form data conn.setRequestProperty("Content-Type", "multipart/related; boundary=" + boundry); // connection.setRequestProperty("MIME-version", "1.0"); DataOutputStream out = new DataOutputStream(conn.getOutputStream()); // out.write(("--" + boundry + " ").getBytes()); // write some fields // name=surveyname, acknowledgment=tunnelupload, copyright=left writeField(out, "name-name", name); writeField(out, "acknowledgment", "tunnelupload"); writeField(out, "copyright", "left"); writeField(out, "tunnelversion", TN.tunnelversion); //writeField(out, "spatial_reference_system", "WGS84-UTM30"); int srsid = 31285; // MGI / M31 //if (spatial_reference_system.equals("OS Grid SD")) // srsid = 13000; double cavealtitude = 1800.0; writeField(out, "at-srsid", String.valueOf(srsid)); // we want to get these all coming in from the change things // the GPS signals are 50 apart. // GPS from the Ireby is *fix 001 66668.00 78303.00 319.00 ;GPS Added 09/01/05 N.P double gpx = cornercoordX; double gpy = cornercoordY; //double gpx = 532601 + (cornercoordX - 66668.00); //double gpy = 6004830 + (cornercoordY - 78303.00); double d100 = dpmetrereal * 100; String sd100 = String.valueOf(d100); String sdYbot = String.valueOf(bi.getHeight()); String sdYbotup100 = String.valueOf(bi.getHeight() - d100); writeField(out, "p1-worldX", String.valueOf(gpx)); writeField(out, "p1-worldY", String.valueOf(gpy - 100)); writeField(out, "p1-imageX", "0"); writeField(out, "p1-imageY", sdYbotup100); writeField(out, "p2-worldX", String.valueOf(gpx + 100)); writeField(out, "p2-worldY", String.valueOf(gpy - 100)); writeField(out, "p2-imageX", sd100); writeField(out, "p2-imageY", sdYbotup100); writeField(out, "p3-worldX", String.valueOf(gpx)); writeField(out, "p3-worldY", String.valueOf(gpy)); writeField(out, "p3-imageX", "0"); writeField(out, "p3-imageY", sdYbot); writeField(out, "at-average_image_altitude", String.valueOf(cavealtitude)); // Write out the bytes of the content string to the stream. writeTileImageFile(out, "name-image", name + ".png", bi); out.writeBytes("--"); out.writeBytes(boundry); out.writeBytes("--"); out.writeBytes("\r\n"); out.flush(); out.close(); BufferedReader fin = new BufferedReader(new InputStreamReader(conn.getInputStream())); String fline; System.out.println("Server response:"); while ((fline = fin.readLine()) != null) System.out.println(":" + fline); fin.close(); } catch (MalformedURLException e) { TN.emitWarning("yyy");} catch (IOException e) { TN.emitWarning("eee " + e.toString());}; } public static String SimplePost(URL url, List args) throws IOException { URLConnection conn = url.openConnection(); conn.setDoInput(true); conn.setDoOutput(true); conn.setUseCaches(false); conn.setRequestProperty("Content-Type", "multipart/related; boundary=" + boundry); DataOutputStream out = new DataOutputStream(conn.getOutputStream()); for (int i = 1; i < args.size(); i += 2) writeField(out, args.get(i-1), args.get(i)); out.writeBytes("--"); out.writeBytes(boundry); out.writeBytes("--"); out.writeBytes("\r\n"); out.flush(); out.close(); BufferedReader fin = new BufferedReader(new InputStreamReader(conn.getInputStream())); StringBuffer response = new StringBuffer(); String fline; while ((fline = fin.readLine()) != null) { response.append(fline); response.append(TN.nl); } fin.close(); return response.toString(); } } tunnelx-20140102.orig/src/TunnelXMLparse.java0000644000000000000000000007010312261213471015602 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // FoUndation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.geom.Line2D; import java.util.List; import java.util.ArrayList; import java.awt.Font; import java.awt.Color; import java.awt.geom.AffineTransform; ///////////////////////////////////////////// class TunnelXMLparse extends TunnelXMLparsebase { String fnamess; int iftype; // the type from TunnelXML List ssba = new ArrayList(); // the structure with a list of symbols in an aut-symbol. -- should be another class. String autsymbdname; String autsymbdesc; int iautsymboverwrite; // 0 no button, 1 overwrite, 2 append // set directly after the constructor is called boolean bSymbolType = false; SketchLineStyle sketchlinestyle = null; // always there if it's a symbol type SubsetAttrStyle subsetattributestyle = null; SubsetAttr subsetattributes = null; SketchGrid sketchgrid = null; SketchFrameDef sketchframedef = null; ///////////////////////////////////////////// // sketch type loading OneSketch tunnelsketch = null; List lvnodes = new ArrayList(); // sketch path loading OnePath sketchpath = null; int sketchpath_ind0; int sketchpath_ind1; int skpnpoints; float skpX; float skpY; float skpZ; boolean skpZset; float skpXo; float skpYo; // set when pulling in labels where the raw xml should be copied over. int isblabelstackpos = -1; boolean bTextType; // should be deprecated. StringBuffer sblabel = new StringBuffer(); static int PFT_NONE = 0; static int PFT_FIX = 1; static int PFT_POSFIX = 2; static int PFT_LEG = 3; int posfixtype = PFT_NONE; ///////////////////////////////////////////// OnePathNode LoadSketchNode(int ind) { while (lvnodes.size() <= ind) lvnodes.add(null); OnePathNode res; if (lvnodes.get(ind) == null) { res = new OnePathNode(skpX, skpY, skpZ); lvnodes.set(ind, res); } else { res = lvnodes.get(ind); if (((float)res.pn.getX() != skpX) || ((float)res.pn.getY() != skpY)) TN.emitWarning("Node mismatch value: " + (float)res.pn.getX() + " = " + skpX + ", " + (float)res.pn.getY() + " = " + skpY); if ((float)res.zalt != skpZ) TN.emitWarning("ZNode mismatch value: " + res.zalt + " = " + skpZ); } return res; } ///////////////////////////////////////////// Color SeStackColour(String name, Color defalt) { String coldef = SeStack(name); if (coldef == null) return defalt; if (coldef.equals("none")) return null; if (!coldef.startsWith("#")) TN.emitError("Colour value should be hex starting with #"); int col = (int)Long.parseLong(coldef.substring(1), 16); return new Color(col, ((col & 0xff000000) != 0)); } ///////////////////////////////////////////// static int isasloadorder = 1000; public void startElementAttributesHandled(String name, boolean binlineclose) { // copy into label stuff if one is live. // this is code in a label (now obsolete because I mangle the text as it goes out) if (isblabelstackpos != -1) { // re-build the // hand-make this case back into proper form!! if (name.equals(TNXML.sLRSYMBOL)) { sblabel.append("<"); sblabel.append(TNXML.sLRSYMBOL); sblabel.append(" "); sblabel.append(TNXML.sLRSYMBOL_NAME); sblabel.append("=\""); sblabel.append(SeStack(TNXML.sLRSYMBOL_NAME)); sblabel.append("\"/>"); } else sblabel.append(TNXML.xcomopen(0, name)); } // go through the possible commands else if (name.equals(TNXML.sLAUT_SYMBOL)) { assert iftype == FileAbstraction.FA_FILE_XML_FONTCOLOURS; // till we make a special class, the list of symbols in an aut-symbol is // a list with first element a string. ssba.clear(); autsymbdname = SeStack(TNXML.sLAUT_SYMBOL_NAME); autsymbdesc = SeStack(TNXML.sLAUT_DESCRIPTION); String sbuttonaction = SeStack(TNXML.sLAUT_BUTTON_ACTION, TNXML.sLAUT_OVERWRITE); if (sbuttonaction.equals(TNXML.sLAUT_OVERWRITE)) iautsymboverwrite = 1; else if (sbuttonaction.equals(TNXML.sLAUT_APPEND)) iautsymboverwrite = 2; else // TNXML.sLAUT_NOBUTTON iautsymboverwrite = 0; } // // values from the fontcolours.xml file // else if (name.equals(TNXML.sSUBSET_ATTRIBUTE_STYLE)) { assert subsetattributestyle == null; String subsetattrstylename = SeStack(TNXML.sSUBSET_ATTRIBUTE_STYLE_NAME); // could use sketchlinestyle.GetSubsetSelection(String lstylename) here if (sketchlinestyle.subsetattrstylesmap.containsKey(subsetattrstylename)) { TN.emitWarning(" *** Removing subsetattribute style of duplicate: " + subsetattrstylename); sketchlinestyle.subsetattrstylesmap.remove(subsetattrstylename); } boolean bselectable = SeStack(TNXML.sSUBSET_ATTRIBUTE_STYLE_SELECTABLE, "yes").equals("yes"); subsetattributestyle = new SubsetAttrStyle(subsetattrstylename, isasloadorder++, bselectable); } else if (name.equals(TNXML.sSUBSET_ATTRIBUTE_STYLE_IMPORT)) { assert subsetattributes == null; String sasname = SeStack(TNXML.sSUBSET_ATTRIBUTE_STYLE_NAME); SubsetAttrStyle lsas = sketchlinestyle.subsetattrstylesmap.get(sasname); if (lsas != null) subsetattributestyle.ImportSubsetAttrStyle(lsas); else TN.emitError("Could not find Subset Attr Style: " + sasname); } // dual use of this as name when it was just a parameter else if (name.equals(TNXML.sASIGNAL_SKETCHFRAME) && (sketchframedef != null)) { sketchframedef.sfscaledown = (float)DeStack(TNXML.sASIG_FRAME_SCALEDOWN, 1.0); sketchframedef.sfrotatedeg = (float)DeStack(TNXML.sASIG_FRAME_ROTATEDEG, 0.0); sketchframedef.sfelevrotdeg = (float)DeStack(TNXML.sASIG_FRAME_ELEVROTDEG, 0.0); sketchframedef.sfelevvertplane = SeStack(TNXML.sASIG_FRAME_ELEVVERTPLANE, ""); sketchframedef.sfxtrans = DeStack(TNXML.sASIG_FRAME_XTRANS, 0.0); sketchframedef.sfytrans = DeStack(TNXML.sASIG_FRAME_YTRANS, 0.0); sketchframedef.sfsketch = SeStack(TNXML.sASIG_FRAME_SKETCH, ""); sketchframedef.sfstyle = SeStack(TNXML.sASIG_FRAME_STYLE, ""); sketchframedef.sfnodeconnzsetrelative = (float)DeStack(TNXML.sASIG_NODECONN_ZSETRELATIVE, 0.0); sketchframedef.imagepixelswidth = IeStack(TNXML.sASIG_FRAME_IMGPIXELWIDTH, -1); sketchframedef.imagepixelsheight = IeStack(TNXML.sASIG_FRAME_IMGPIXELHEIGHT, -1); } // the sneaky parsing for a sketchframedef case else if (name.equals(TNXML.sSUBSET_ATTRIBUTES) && (sketchframedef != null)) { String ssubset = SeStack(TNXML.sSUBSET_NAME); String uppersubset = SeStack(TNXML.sUPPER_SUBSET_NAME); sketchframedef.submapping.put(ssubset, uppersubset); } // second sneaky read-write of the data when inserted into a sketchpath.plabedl.sketchframedef else if (name.equals(TNXML.sSUBSET_ATTRIBUTES) && (sketchpath != null) && (sketchpath.plabedl != null) && (sketchpath.plabedl.sketchframedef != null)) { String ssubset = SeStack(TNXML.sSUBSET_NAME); String uppersubset = SeStack(TNXML.sUPPER_SUBSET_NAME); sketchpath.plabedl.sketchframedef.submapping.put(ssubset, uppersubset); } // proper case when we're loading a font-colours else if (name.equals(TNXML.sSUBSET_ATTRIBUTES)) { // get the subset attributes if (subsetattributes != null) TN.emitError("subset def inside subset def " + SeStack(TNXML.sSUBSET_NAME)); String ssubset = SeStack(TNXML.sSUBSET_NAME); subsetattributes = subsetattributestyle.msubsets.get(ssubset); if (subsetattributes == null) { subsetattributes = new SubsetAttr(ssubset); subsetattributestyle.msubsets.put(ssubset, subsetattributes); } // use default value to map through non-overwritten attributes subsetattributes.uppersubset = SeStack(TNXML.sUPPER_SUBSET_NAME, subsetattributes.uppersubset); subsetattributes.sareamaskcolour = SeStack(TNXML.sSUBSET_AREAMASKCOLOUR, subsetattributes.sareamaskcolour); subsetattributes.sareacolour = SeStack(TNXML.sSUBSET_AREACOLOUR, subsetattributes.sareacolour); } else if (name.equals(TNXML.sSET_ATTR_VARIABLE)) { assert subsetattributes != null; subsetattributes.SetVariable(SeStack(TNXML.sATTR_VARIABLE_NAME), SeStack(TNXML.sATTR_VARIABLE_VALUE)); } else if (name.equals(TNXML.sLABEL_STYLE_FCOL)) { assert subsetattributes != null; String llabelfontname = SeStack(TNXML.sLABEL_STYLE_NAME); LabelFontAttr lfa = subsetattributes.labelfontsmap.get(llabelfontname); if (lfa == null) { lfa = new LabelFontAttr(llabelfontname, subsetattributes); //System.out.println("LLL " + subsetattributes.subsetname + " " + llabelfontname); subsetattributes.labelfontsmap.put(llabelfontname, lfa); } else TN.emitWarning("Over-writing data in font " + llabelfontname + " in subset " + subsetattributes.subsetname); lfa.sfontname = SeStack(TNXML.sLABEL_FONTNAME, null); lfa.sfontstyle = SeStack(TNXML.sLABEL_FONTSTYLE, null); lfa.slabelcolour = SeStack(TNXML.sLABEL_COLOUR, null); lfa.sfontsize = SeStack(TNXML.sLABEL_FONTSIZE, null); } else if (name.equals(TNXML.sLINE_STYLE_COL)) { assert subsetattributes != null; String slinestyle = SeStack(TNXML.sSK_LINESTYLE); int llinestyle = TNXML.DecodeLinestyle(slinestyle); subsetattributes.SetLinestyleAttr(llinestyle, SeStack(TNXML.sLS_STROKEWIDTH), SeStack(TNXML.sLS_SPIKEGAP), SeStack(TNXML.sLS_GAPLENG), SeStack(TNXML.sLS_SPIKEHEIGHT), SeStack(TNXML.sLS_STROKECOLOUR), SeStack(TNXML.sLS_SHADOWSTROKEWIDTH, "0"), SeStack(TNXML.sLS_SHADOWSTROKECOLOUR, null)); } // these are per attribute style else if (name.equals(TNXML.sGRID_DEF)) { assert subsetattributestyle != null; subsetattributestyle.sketchgrid = new SketchGrid((float)DeStack(TNXML.sGRID_XORIG), (float)DeStack(TNXML.sGRID_YORIG)); sketchgrid = subsetattributestyle.sketchgrid; } else if (name.equals(TNXML.sGRID_SPACING)) { float fspacing = (float)DeStack(TNXML.sGRID_SPACING_WIDTH); assert sketchgrid.ngridspacing < sketchgrid.gridspacing.length; assert (sketchgrid.ngridspacing == 0) || (fspacing > sketchgrid.gridspacing[sketchgrid.ngridspacing - 1]); sketchgrid.gridspacing[sketchgrid.ngridspacing] = fspacing; sketchgrid.gridlineslimit[sketchgrid.ngridspacing] = IeStack(TNXML.sMAX_GRID_LINES); sketchgrid.ngridspacing++; } // these are on their own else if (name.equals(TNXML.sAREA_SIG_DEF)) { //System.out.println("sshshsh " + SeStack(TNXML.sAREA_SIG_NAME) + " " + SketchLineStyle.nareasignames); SketchLineStyle.areasignames[SketchLineStyle.nareasignames] = SeStack(TNXML.sAREA_SIG_NAME); String lasigeffect = SeStack(TNXML.sAREA_SIG_EFFECT); // this magic value gets maximized around the contour int isigeffect = SketchLineStyle.ASE_KEEPAREA; if (lasigeffect.equals(TNXML.sASIGNAL_KEEPAREA)) isigeffect = SketchLineStyle.ASE_KEEPAREA; else if (lasigeffect.equals(TNXML.sASIGNAL_KILLAREA)) isigeffect = SketchLineStyle.ASE_KILLAREA; else if (lasigeffect.equals(TNXML.sASIGNAL_OUTLINEAREA)) isigeffect = SketchLineStyle.ASE_OUTLINEAREA; else if (lasigeffect.equals(TNXML.sASIGNAL_HCOINCIDE)) isigeffect = SketchLineStyle.ASE_HCOINCIDE; else if (lasigeffect.equals(TNXML.sASIGNAL_SKETCHFRAME)) isigeffect = SketchLineStyle.ASE_SKETCHFRAME; else if (lasigeffect.equals(TNXML.sASIGNAL_ZSETRELATIVE)) isigeffect = SketchLineStyle.ASE_ZSETRELATIVE; else if (lasigeffect.equals(TNXML.sASIGNAL_ELEVATIONPATH)) isigeffect = SketchLineStyle.ASE_ELEVATIONPATH; else TN.emitWarning("Unrecognized area signal " + lasigeffect); if (isigeffect == SketchLineStyle.ASE_ELEVATIONPATH) SketchLineStyle.iareasigelev = SketchLineStyle.nareasignames; if (isigeffect == SketchLineStyle.ASE_SKETCHFRAME) SketchLineStyle.iareasigframe = SketchLineStyle.nareasignames; SketchLineStyle.areasigeffect[SketchLineStyle.nareasignames] = isigeffect; SketchLineStyle.nareasignames++; } // the directory names where images can be stored else if (name.equals(TNXML.sIMAGE_FILE_DIRECTORY)) FileAbstraction.AddImageFileDirectory(SeStack(TNXML.sIMAGE_FILE_DIRECTORY_NAME)); else if (name.equals(TNXML.sDIRECTORY)) { String ldirectoryname = SeStack(TNXML.sNAME); if (FileAbstraction.isDirectory(ldirectoryname)) { if (SeStack(TNXML.sDIRECTORY_APPLICATION).equals("inkscape")) TN.inkscapeexecutabledir = ldirectoryname; } } else if (name.equals(TNXML.sSURVEXEXEDIR)) { if (!FileAbstraction.bIsApplet) { // in the future the final case is to allow this to be a URL which calls back to the internet to process the svx file String lsurvexexecutabledir = SeStack(TNXML.sNAME); if (FileAbstraction.isDirectory(lsurvexexecutabledir)) TN.survexexecutabledir = lsurvexexecutabledir; } } // go through the possible commands else if (name.equals(TNXML.sMEASUREMENTS)) TN.emitError("We don't read measurements files anymore"); else if (name.equals(TNXML.sEXPORTS)) TN.emitError("We don't read Exports file anymore"); // the replacement of labels else if (name.equals(TNXML.sPATHCODES)) { // make the label decode object sketchpath.plabedl = new PathLabelDecode(); } // the replacement of labels else if (name.equals(TNXML.sPC_TEXT)) { // make the label decode object isblabelstackpos = istack - 1; bTextType = false; sketchpath.plabedl.sfontcode = SeStack(TNXML.sLTEXTSTYLE, "default"); sketchpath.plabedl.fnodeposxrel = (float)DeStack(TNXML.sPC_NODEPOSXREL, -1.0); sketchpath.plabedl.fnodeposyrel = (float)DeStack(TNXML.sPC_NODEPOSYREL, -1.0); sketchpath.plabedl.barrowpresent = SeStack(TNXML.sPC_ARROWPRES, "0").equals("1"); sketchpath.plabedl.bboxpresent = SeStack(TNXML.sPC_BOXPRES, "0").equals("1"); } else if (name.equals(TNXML.sCL_STATIONS)) { sketchpath.plabedl.centrelinetail = SeStack(TNXML.sCL_TAIL, null); sketchpath.plabedl.centrelinehead = SeStack(TNXML.sCL_HEAD, null); sketchpath.plabedl.centrelineelev = SeStack(TNXML.sCL_ELEV, null); } else if (name.equals(TNXML.sPC_AREA_SIGNAL)) { String arpres = SeStack(TNXML.sAREA_PRESENT); sketchpath.plabedl.iarea_pres_signal = -1; for (int i = 0; i < sketchlinestyle.nareasignames; i++) if (arpres.equals(sketchlinestyle.areasignames[i])) sketchpath.plabedl.iarea_pres_signal = i; if (sketchpath.plabedl.iarea_pres_signal == -1) { TN.emitWarning("Unrecognized area signal:" + arpres); sketchpath.plabedl.iarea_pres_signal = 0; } sketchpath.plabedl.barea_pres_signal = sketchlinestyle.areasigeffect[sketchpath.plabedl.iarea_pres_signal]; if (sketchpath.plabedl.barea_pres_signal == SketchLineStyle.ASE_SKETCHFRAME) { sketchpath.plabedl.sketchframedef = new SketchFrameDef(); sketchpath.plabedl.sketchframedef.sfscaledown = (float)DeStack(TNXML.sASIG_FRAME_SCALEDOWN); sketchpath.plabedl.sketchframedef.sfrotatedeg = (float)DeStack(TNXML.sASIG_FRAME_ROTATEDEG); sketchpath.plabedl.sketchframedef.sfelevrotdeg = (float)DeStack(TNXML.sASIG_FRAME_ELEVROTDEG, 0.0); sketchpath.plabedl.sketchframedef.sfelevvertplane = SeStack(TNXML.sASIG_FRAME_ELEVVERTPLANE, ""); sketchpath.plabedl.sketchframedef.sfxtrans = DeStack(TNXML.sASIG_FRAME_XTRANS); sketchpath.plabedl.sketchframedef.sfytrans = DeStack(TNXML.sASIG_FRAME_YTRANS); sketchpath.plabedl.sketchframedef.sfsketch = SeStack(TNXML.sASIG_FRAME_SKETCH); sketchpath.plabedl.sketchframedef.sfstyle = SeStack(TNXML.sASIG_FRAME_STYLE); sketchpath.plabedl.sketchframedef.sfnodeconnzsetrelative = (float)DeStack(TNXML.sASIG_NODECONN_ZSETRELATIVE, 0.0); sketchpath.plabedl.sketchframedef.imagepixelswidth = IeStack(TNXML.sASIG_FRAME_IMGPIXELWIDTH, -1); sketchpath.plabedl.sketchframedef.imagepixelsheight = IeStack(TNXML.sASIG_FRAME_IMGPIXELHEIGHT, -1); } else if (sketchpath.plabedl.barea_pres_signal == SketchLineStyle.ASE_ZSETRELATIVE) sketchpath.plabedl.nodeconnzsetrelative = (float)DeStack(TNXML.sASIG_NODECONN_ZSETRELATIVE); } // the symbols else if (name.equals(TNXML.sPC_RSYMBOL)) sketchpath.plabedl.vlabsymb.add(SeStack(TNXML.sLRSYMBOL_NAME)); // deprecated else if (name.equals(TNXML.sLABEL)) { TN.emitWarning("deprecated label type"); isblabelstackpos = istack - 1; bTextType = false; } // deprecated else if (name.equals(TNXML.sTEXT)) { TN.emitWarning("deprecated text type"); isblabelstackpos = istack - 1; bTextType = true; } // open a sketch else if (name.equals(TNXML.sSKETCH)) { assert iftype == FileAbstraction.FA_FILE_XML_SKETCH; assert tunnelsketch != null; lvnodes.clear(); assert tunnelsketch.bSymbolType == bSymbolType; if (SeStack(TNXML.sSKETCH_LOCOFFSETX) != null) tunnelsketch.sketchLocOffset.SetXYZ((float)DeStack(TNXML.sSKETCH_LOCOFFSETX), (float)DeStack(TNXML.sSKETCH_LOCOFFSETY), (float)DeStack(TNXML.sSKETCH_LOCOFFSETZ)); if (SeStack(TNXML.sSKETCH_REALPAPERSCALE) != null) tunnelsketch.realposterpaperscale = DeStack(TNXML.sSKETCH_REALPAPERSCALE); tunnelsketch.tunnelprojectloaded = SeStack(TNXML.sTUNNELPROJECT, ""); tunnelsketch.tunnelversionloaded = SeStack(TNXML.sTUNNELVERSION, ""); tunnelsketch.tunneldateloaded = SeStack(TNXML.sTUNNELDATE, ""); tunnelsketch.tunneluserloaded = SeStack(TNXML.sTUNNELUSER, ""); } // open a xsection else if (name.equals(TNXML.sXSECTION)) TN.emitWarning("No longer XSection" + TNXML.sXSECTION); // make a tube else if (name.equals(TNXML.sLINEAR_TUBE)) TN.emitWarning("dead type: " + TNXML.sLINEAR_TUBE); // open a posfix (not input as are the legs not input). else if (name.equals(TNXML.sFIX)) posfixtype = PFT_FIX; else if (name.equals(TNXML.sPOS_FIX)) posfixtype = PFT_POSFIX; else if (name.equals(TNXML.sLEG)) posfixtype = PFT_LEG; // aut-symbols thing else if (name.equals(TNXML.sLASYMBOL)) { SSymbolBase ssb = new SSymbolBase(); // decode the mcode attributes on the symbol // this provides the interface between the xml and the values in the base class. String sscale = SeStack(TNXML.sLAUT_SYMBOL_SCALE, TNXML.sLAUT_SYMBOL_ALONGAXIS); ssb.bScaleable = !sscale.equals(TNXML.sLAUT_SYMBOL_FIXED); ssb.bShrinkby2 = sscale.equals(TNXML.sLAUT_SYMBOL_ANDHALF); if (ssb.bShrinkby2) ssb.bScaleable = false; ssb.fpicscale = (float)DeStack(TNXML.sLAUT_SYMBOL_PICSCALE, 1.0); ssb.faxisscale = (float)DeStack(TNXML.sLAUT_SYMBOL_AXISSCALE, 1.0); ssb.faxisscaleperp = (float)DeStack(TNXML.sLAUT_SYMBOL_AXISSCALEPERP, 1.0); String sorientation = SeStack(TNXML.sLAUT_SYMBOL_ORIENTATION, TNXML.sLAUT_SYMBOL_ALONGAXIS); ssb.bRotateable = !sorientation.equals(TNXML.sLAUT_SYMBOL_FIXED); if (sorientation.equals(TNXML.sLAUT_SYMBOL_RANDOM)) ssb.posangledeviation = -1.0F; else if (sorientation.equals(TNXML.sLAUT_SYMBOL_ALONGAXIS)) ssb.posangledeviation = 0.0F; else if (sorientation.equals(TNXML.sLAUT_SYMBOL_ALONGAXIS_PERP)) ssb.posangledeviation = -2.0F; else if (sorientation.equals(TNXML.sLAUT_SYMBOL_NEARAXIS)) ssb.posangledeviation = 0.1F; // position setting String sposition = SeStack(TNXML.sLAUT_SYMBOL_POSITION, TNXML.sLAUT_SYMBOL_ENDPATH); ssb.bMoveable = !sposition.equals(TNXML.sLAUT_SYMBOL_ENDPATH); ssb.iLattice = (sposition.equals(TNXML.sLAUT_SYMBOL_LATTICEF) ? 2 : (sposition.equals(TNXML.sLAUT_SYMBOL_LATTICE) ? 1 : 0)); ssb.bPullback = sposition.equals(TNXML.sLAUT_SYMBOL_PULLBACK); ssb.bPushout = sposition.equals(TNXML.sLAUT_SYMBOL_PUSHOUT); ssb.posdeviationprop = (ssb.bMoveable && (ssb.iLattice == 0) ? (ssb.bPullback ? 2.0F : 1.0F) : 0.0F); String aint = SeStack(TNXML.sLAUT_SYMBOL_AINT, TNXML.sLAUT_SYMBOL_AINT_NO_OVERLAP); ssb.bAllowedOutsideArea = !aint.equals(TNXML.sLAUT_SYMBOL_AINT_NO_OVERLAP); ssb.bTrimByArea = aint.equals(TNXML.sLAUT_SYMBOL_AINT_TRIM); ssb.bSymbolinterferencedoesntmatter = aint.equals(TNXML.sLAUT_SYMBOL_AINT_ALLOWED_OUTSIDE); String filledtype = SeStack(TNXML.sLAUT_SYMBOL_DRAWSTYLE, TNXML.sLAUT_SYMBOL_DRAWSTYLE_LINE); ssb.bFilledType = filledtype.equals(TNXML.sLAUT_SYMBOL_DRAWSTYLE_FILLED); ssb.gsymname = SeStack(TNXML.sLSYMBOL_NAME); String smultiplicity = SeStack(TNXML.sLAUT_SYMBOL_MULTIPLICITY, "1"); ssb.nmultiplicity = (smultiplicity.equals(TNXML.sLAUT_SYMBOL_MULTIPLICITY_FILL) ? -1 : Integer.parseInt(smultiplicity)); ssb.symbolareafillcolour = SeStackColour(TNXML.sLAUT_SYMBOL_AREA_FILL, null); // we build a lattice in area fills or lattice types ssb.bBuildSymbolLatticeAcrossArea = (sposition.equals(TNXML.sLAUT_SYMBOL_LATTICEF) || sposition.equals(TNXML.sLAUT_SYMBOL_LATTICE) || smultiplicity.equals(TNXML.sLAUT_SYMBOL_MULTIPLICITY_FILL)); ssb.bSymbolLatticeAcrossAreaPhased = (sposition.equals(TNXML.sLAUT_SYMBOL_LATTICEF) || smultiplicity.equals(TNXML.sLAUT_SYMBOL_MULTIPLICITY_FILL)); ssb.bBuildSymbolSpreadAlongLine = (sposition.equals(TNXML.sLAUT_SYMBOL_ALONGPATH_RANDOM_PULLBACK) || sposition.equals(TNXML.sLAUT_SYMBOL_ALONGPATH_EVEN)); ssb.bSymbolLayoutOrdered = (sposition.equals(TNXML.sLAUT_SYMBOL_LATTICEF) || sposition.equals(TNXML.sLAUT_SYMBOL_LATTICE) || sposition.equals(TNXML.sLAUT_SYMBOL_ALONGPATH_EVEN)); if (ssb.bBuildSymbolSpreadAlongLine) ssb.posdeviationprop = (sposition.equals(TNXML.sLAUT_SYMBOL_ALONGPATH_RANDOM_PULLBACK) ? 1.0 : 0.0); if (sposition.equals(TNXML.sLAUT_SYMBOL_ALONGPATH_RANDOM_PULLBACK)) { ssb.bPullback = true; ssb.bSymbolLayoutOrdered = true; ssb.posdeviationprop = 0.1F; } ssb.bOrientClosestAlongLine = sorientation.equals(TNXML.sLAUT_SYMBOL_CLOSESTFROMAXIS); ssb.bOrientClosestPerpLine = sorientation.equals(TNXML.sLAUT_SYMBOL_CLOSESTALONGAXIS); // first entry of this vector is a string of the name ssba.add(ssb); } // as a batch //static String sTAPE = "tape"; //static String sCOMPASS = "compass"; //static String sCLINO = "clino"; // sketch things else if (name.equals(TNXML.sSKETCH_PATH)) { sketchpath_ind0 = IeStack(TNXML.sFROM_SKNODE); sketchpath_ind1 = IeStack(TNXML.sTO_SKNODE); sketchpath = new OnePath(); skpnpoints = 0; sketchpath.linestyle = TNXML.DecodeLinestyle(SeStack(TNXML.sSK_LINESTYLE)); sketchpath.bWantSplined = (IeStack(TNXML.sSPLINED) != 0); } // subset markers else if (name.equals(TNXML.sSKSUBSET)) { String ssubset = SeStack(TNXML.sSKSNAME); sketchpath.vssubsets.add(ssubset); tunnelsketch.sallsubsets.add(ssubset); } else if (name.equals(TNXML.sSKIMPORTFROM)) sketchpath.importfromname = SeStack(TNXML.sSKSNAME); else if (name.equals(TNXML.sPOINT)) { skpX = (float)DeStack(TNXML.sPTX); skpY = (float)DeStack(TNXML.sPTY); // the z value gets saved only in the case of centreline nodes String sptz = SeStack(TNXML.sPTZ); skpZset = (sptz != null); skpZ = (skpZset ? Float.parseFloat(sptz) : 0.0F); if (sketchpath != null) { if (skpnpoints == 0) { sketchpath.gp.moveTo(skpX, skpY); sketchpath.pnstart = LoadSketchNode(sketchpath_ind0); } else sketchpath.LineTo(skpX, skpY); skpnpoints++; } else if (posfixtype != PFT_NONE) ; // nothing input for now. // supress errors on these no longer existent types else if (ElStack("symbol")) ; else { StackDump(); TN.emitError("point without an object"); } } } ///////////////////////////////////////////// public void characters(String pstr) { // whitespace that shouldn't comes through here. assert pstr != null; if (isblabelstackpos != -1) { // deprecated if (bTextType) { String txt = pstr; int ip = pstr.indexOf("%%"); if (ip != -1) { sblabel.append(TNXML.xcomtext(TNXML.sTAIL, pstr.substring(0, ip))); sblabel.append(TNXML.xcomtext(TNXML.sHEAD, pstr.substring(ip + 2))); } } else sblabel.append(pstr); } } static PathLabelXMLparse BBplxp = new PathLabelXMLparse(); ///////////////////////////////////////////// public void endElementAttributesHandled(String name) { // middle or ending of labels. if (isblabelstackpos != -1) { // ending. if (isblabelstackpos == istack) { if (name.equals(TNXML.sPC_TEXT)) { sketchpath.plabedl.drawlab = TNXML.xunmanglxmltext(sblabel.toString()); sblabel.setLength(0); isblabelstackpos = -1; } else if (name.equals(TNXML.sLABEL)) { // I think this is just for backward compatibility TN.emitWarning("*** Using Label parameter: " + sblabel.toString()); sketchpath.plabedl = new PathLabelDecode(); BBplxp.ParseLabel(sketchpath.plabedl, TNXML.xunmanglxmltext(sblabel.toString()), sketchlinestyle); // this is where labels are at present added. sblabel.setLength(0); isblabelstackpos = -1; } else { if (!bTextType || !name.equals(TNXML.sTEXT)) TN.emitProgError("Stack pos doesn't match label position"); else TN.emitWarning("Deprecated TEXT type used for label"); } } // the closing thing already done earlier (note the !) else if (!name.equals(TNXML.sLRSYMBOL)) sblabel.append(TNXML.xcomclose(0, name)); } // ending of other items. else if (name.equals(TNXML.sSKETCH)) { assert OnePathNode.CheckAllPathCounts(tunnelsketch.vnodes, tunnelsketch.vpaths); tunnelsketch = null; iftype = FileAbstraction.FA_FILE_UNKNOWN; // so only one in } else if (name.equals(TNXML.sMEASUREMENTS)) iftype = FileAbstraction.FA_FILE_UNKNOWN; else if (name.equals(TNXML.sSKETCH_PATH)) { sketchpath.EndPath(LoadSketchNode(sketchpath_ind1)); tunnelsketch.TAddPath(sketchpath, null); if (!tunnelsketch.bSymbolType && (sketchpath.linestyle == SketchLineStyle.SLS_CENTRELINE) && (sketchpath.plabedl != null)) sketchpath.UpdateStationLabelsFromCentreline(); sketchpath = null; } else if (name.equals(TNXML.sFIX) || name.equals(TNXML.sPOS_FIX) || name.equals(TNXML.sLEG)) posfixtype = PFT_NONE; else if (name.equals(TNXML.sLAUT_SYMBOL)) { assert (subsetattributes != null); SymbolStyleAttr ssa = subsetattributes.subautsymbolsmap.get(autsymbdname); if (ssa == null) { ssa = new SymbolStyleAttr(autsymbdname); subsetattributes.subautsymbolsmap.put(autsymbdname, ssa); } else TN.emitWarning("Over-writing symbol " + autsymbdname + " in subset " + subsetattributes.subsetname); ssa.iautsymboverwrite = iautsymboverwrite; ssa.autsymbdesc = autsymbdesc; ssa.ssymbolbs = new ArrayList(); ssa.ssymbolbs.addAll(ssba); } // used for the fontcolours else if (name.equals(TNXML.sSUBSET_ATTRIBUTE_STYLE)) { assert !sketchlinestyle.subsetattrstylesmap.containsKey(subsetattributestyle.stylename); sketchlinestyle.subsetattrstylesmap.put(subsetattributestyle.stylename, subsetattributestyle); sketchlinestyle.bsubsetattributesneedupdating = true; subsetattributestyle.AssignDefault(null); subsetattributestyle = null; } else if (name.equals(TNXML.sGRID_DEF)) { assert sketchgrid.ngridspacing != 0; sketchgrid = null; } else if (name.equals(TNXML.sSUBSET_ATTRIBUTES)) { if (sketchframedef == null) subsetattributes = null; } else if (name.equals(TNXML.sFONTCOLOURS)) ; // sketchlinestyle.symbolsdisplay.MakeSymbolButtonsInPanel(); } ///////////////////////////////////////////// ///////////////////////////////////////////// TunnelXMLparse() { } ///////////////////////////////////////////// void SetUp(String lfnamess, int liftype) { SetUpBase(); fnamess = lfnamess; iftype = liftype; tunnelsketch = null; sketchpath = null; isblabelstackpos = -1; sblabel.setLength(0); posfixtype = 0; } }; tunnelx-20140102.orig/src/LineInputStream.java0000644000000000000000000001462511762432750016023 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.io.IOException; import java.io.BufferedReader; import java.io.FileReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.StringReader; import java.net.URL; // // // LineInputStream // // ///////////////////////////////////////////// public class LineInputStream extends BufferedReader { private String bufferline = ""; private String unfetchline = null; // the expansion of the bufferline int MAX_WORDS = 12; public int iwc = MAX_WORDS; // the first clear element of w. public String w[] = new String[MAX_WORDS]; public String remainder = ""; // this is rest of line after the first word (usually for titles). public String remainder1 = ""; public String remainder2 = ""; public String comment = ""; FileAbstraction loadfile = null; InputStream inputstream = null; // recorded so we can do a close on it so django runserver works String slash; int nlineno; // botch stuff to convert *prefix code to a *begin *end couplet. String prefixconversion; ///////////////////////////////////////////// public LineInputStream(InputStream linputstream, FileAbstraction lloadfile, String lslash, String lprefixconversion) throws IOException { super(new InputStreamReader(linputstream)); slash = lslash; loadfile = lloadfile; inputstream = linputstream; nlineno = 0; prefixconversion = lprefixconversion; // TN.emitMessage(loadfile.getName() + " Slash:" + slash); if (prefixconversion != null) TN.emitMessage(" prefixconversion: " + prefixconversion); } ///////////////////////////////////////////// public LineInputStream(String text, FileAbstraction lloadfile) { super(new StringReader(text)); loadfile = lloadfile; // for error messages (to give the right name) SplitWords("", false); // clears the array. } ///////////////////////////////////////////// // newly added function which should be used everywhere in the line reading. void emitError(String mess) { // avoiding repeat errors for now //if (loadfile != null) TN.emitError("File " + (loadfile == null ? "" : loadfile.getName()) + ", line " + nlineno + ", " + mess + "\n" + GetLine()); } ///////////////////////////////////////////// void emitWarning(String mess) { // avoiding repeat errors for now //if (loadfile != null) TN.emitWarning("*** " + (loadfile == null ? "" : "File " + loadfile.getName() + ", ") + "line " + nlineno + ", " + mess + "\n" + GetLine()); } ///////////////////////////////////////////// void emitWarningF(String mess) { // avoiding repeat errors for now TN.emitWarning("File " + (loadfile == null ? "" : loadfile.getName()) + ", line " + nlineno + ", " + mess); } ///////////////////////////////////////////// public boolean FetchNextLine() { if (unfetchline != null) { bufferline = unfetchline; unfetchline = null; SplitWords(bufferline, true); return true; } try { bufferline = readLine(); nlineno++; } catch (IOException ioe) { TN.emitError("IOException thrown in readLine()"); bufferline = null; } if (bufferline != null) { SplitWords(bufferline, true); return true; } else SplitWords("", false); // clears the array. return false; } ///////////////////////////////////////////// public boolean FetchNextLineNoSplit() { if (unfetchline != null) { bufferline = unfetchline; unfetchline = null; return true; } try { bufferline = readLine(); nlineno++; } catch (IOException ioe) { TN.emitError("IOException thrown in readLine()"); bufferline = null; } if (bufferline != null) { return true; } return false; } ///////////////////////////////////////////// public void UnFetch() { if (unfetchline != null) TN.emitWarning("Can't unfetchline twice"); unfetchline = bufferline; } ///////////////////////////////////////////// public String GetLine() { if (bufferline == null) TN.emitMessage("Error: null value passed back from GetLine()"); return bufferline; } ///////////////////////////////////////////// public void SplitWords(String sline, boolean bRepErrors) { comment = ""; remainder = sline.trim(); remainder1 = ""; remainder2 = ""; int iw = 0; while ((remainder.length() != 0) && (iw < MAX_WORDS)) { if (remainder.charAt(0) == ';') { comment = remainder.substring(1); break; } if ((remainder.length() == 1) || (remainder.charAt(0) != '"')) { int ps = remainder.indexOf(' '); int pt = remainder.indexOf('\t'); int pc = remainder.indexOf(','); int psc = remainder.indexOf(';'); int peow = remainder.length(); int pbnw = peow; if ((ps != -1)) { peow = ps; pbnw = ps; } if ((pt != -1) && (pt < peow)) { peow = pt; pbnw = pt; } if ((pc != -1) && (pc < peow)) { peow = pc; pbnw = pc + 1; } if ((psc != -1) && (psc < peow)) { peow = psc; pbnw = psc; } w[iw] = remainder.substring(0, peow); iw++; if (pbnw == remainder.length()) break; remainder = remainder.substring(pbnw).trim(); } else { int pq = remainder.indexOf('"', 1); if (pq == -1) { if (bRepErrors) TN.emitMessage("missing close quote in line: " + sline); break; } w[iw] = remainder.substring(1, pq); iw++; remainder.substring(pq + 1).trim(); } if (iw == 1) remainder1 = remainder; if (iw == 2) remainder2 = remainder; } for (int i = iw; i < iwc; i++) w[i] = ""; iwc = iw; } } tunnelx-20140102.orig/src/SymbolsDisplay.java0000644000000000000000000001347311762432750015716 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JButton; import javax.swing.JTextField; import java.awt.BorderLayout; import java.awt.GridLayout; import java.awt.Insets; import java.util.Set; import java.util.HashSet; import java.util.SortedMap; import java.util.TreeMap; import java.util.List; import java.util.ArrayList; import java.util.Collections; import javax.swing.AbstractAction; import java.awt.event.ActionEvent; // // // SymbolsDisplay // // ///////////////////////////////////////////// // this thing should be disentangleable. class AutSymbolAc extends AbstractAction implements Comparable { SymbolsDisplay symbolsdisplay; String name; String shdesc; boolean bOverwrite; JButton tsymbutt = null; ///////////////////////////////////////////// public AutSymbolAc(String lname, String lshdesc, boolean lbOverwrite, SymbolsDisplay lsymbolsdisplay) { super(lname); shdesc = lshdesc; bOverwrite = lbOverwrite; name = lname; symbolsdisplay = lsymbolsdisplay; putValue(SHORT_DESCRIPTION, shdesc); } ///////////////////////////////////////////// public int compareTo(AutSymbolAc asa) { return name.compareTo(asa.name); } ///////////////////////////////////////////// public void actionPerformed(ActionEvent e) { symbolsdisplay.sketchdisplay.sketchlinestyle.LSpecSymbol(bOverwrite, name); } }; ///////////////////////////////////////////// class SymbolsDisplay extends JPanel { SketchDisplay sketchdisplay; JPanel pansymb = new JPanel(new GridLayout(0, 3)); JButton jbclear = new JButton("Clear"); JButton jbcancel = new JButton("Cancel"); JTextField jbsymlist = new JTextField("--"); SortedMap autsymbsmap = new TreeMap(); SubsetAttr Dsubsetattr = null; // saved and verified to make sure SelEnableButtons has been updated ///////////////////////////////////////////// SymbolsDisplay(SketchDisplay lsketchdisplay) { super(new BorderLayout()); sketchdisplay = lsketchdisplay; add(new JLabel("Symbols", JLabel.CENTER), BorderLayout.NORTH); add(pansymb, BorderLayout.CENTER); jbsymlist.setEditable(false); JPanel psouth = new JPanel(new BorderLayout()); JPanel psouthbutts = new JPanel(); psouthbutts.add(jbclear); psouthbutts.add(jbcancel); psouth.add(jbsymlist, BorderLayout.NORTH); psouth.add(psouthbutts, BorderLayout.SOUTH); add(psouth, BorderLayout.SOUTH); } ///////////////////////////////////////////// void UpdateSymbList(List vlabsymb, SubsetAttr lDsubsetattr) { assert Dsubsetattr == lDsubsetattr; // used to make sure SelEnableButtons is up to date, in case we make new symbols functions if (vlabsymb.isEmpty()) { jbsymlist.setText(""); return; } StringBuffer sb = new StringBuffer(); for (String rname : vlabsymb) { if (sb.length() != 0) sb.append("+"); sb.append(rname); } jbsymlist.setText(sb.toString()); } ///////////////////////////////////////////// Insets defsymbutinsets = new Insets(2, 3, 2, 3); ///////////////////////////////////////////// void SelEnableButtons(SubsetAttr subsetattr) { Dsubsetattr = subsetattr; // for debug verification for (AutSymbolAc autsymbol : autsymbsmap.values()) autsymbol.setEnabled((subsetattr != null) && subsetattr.subautsymbolsmap.containsKey(autsymbol.name)); } ///////////////////////////////////////////// void ReloadSymbolsButtons(SubsetAttrStyle sascurrent) { autsymbsmap.clear(); for (SubsetAttr sa : sascurrent.msubsets.values()) { for (SymbolStyleAttr ssa : sa.subautsymbolsmap.values()) { if (!autsymbsmap.containsKey(ssa.symbolname) && (ssa.iautsymboverwrite != 0)) autsymbsmap.put(ssa.symbolname, new AutSymbolAc(ssa.symbolname, ssa.autsymbdesc, (ssa.iautsymboverwrite == 1), this)); } } pansymb.removeAll(); for (AutSymbolAc autsymbol : autsymbsmap.values()) { JButton symbolbutton = new JButton(autsymbol); symbolbutton.setMargin(defsymbutinsets); autsymbol.tsymbutt = symbolbutton; pansymb.add(symbolbutton); } } }; /* The way to do scalebars is as follows Simple: %10/1%%whiterect% ;%10/1%%blackrect% ;%10/1%%whiterect% ;%10/1%%blackrect% ;%10/1%%whiterect% %10/1%0m ;%10/1%10m ;%10/1%20m ;%10/1%30m ;%10/1%40m ;%10/1%50m Complex: %0/1.0000%%v0/1% ;%50/1%%v1/1%%whiterect% %1/1%%v0.5/1% ;%1/1%%v0.5/1%%blackrect% ;%1/1% ;%1/1%%v0.5/1%%blackrect% ;%1/1% ;%5/1%%v0.5/1%%blackrect% ;%5/1%%v1/1% ;%5/1%%v0.5/1%%blackrect% ;%5/1%%v1/1% ;%5/1%%v0.5/1%%blackrect% ;%5/1%%v1/1% ;%5/1%%v0.5/1%%blackrect% ;%5/1%%v1/1% ;%5/1%%v0.5/1%%blackrect% %1/1%%v0.5/1%%blackrect% ;%1/1% ;%1/1%%v0.5/1%%blackrect% ;%1/1% ;%1/1%%v0.5/1%%blackrect% ;%5/1% ;%5 /1%%v0.5/1%%blackrect% ;%5/1% ;%5 /1%%v0.5/1%%blackrect% ;%5/1% ;%5 /1%%v0.5/1%%blackrect% ;%5/1% ;%5 /1%%v0.5/1%%blackrect% %4.5/1%0m ;%5/1%5m ;%10/1%10m ;%10/1%20m ;%10/1%30m ;%10/1%40m ;%10/1%50m */ tunnelx-20140102.orig/src/SketchSymbolAreas.java0000644000000000000000000003533712261213471016316 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.geom.GeneralPath; import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.AffineTransform; import java.awt.geom.Area; import java.awt.Graphics2D; import java.awt.Shape; import java.awt.geom.Area; import java.awt.Rectangle; import java.util.SortedSet; import java.util.TreeSet; import java.util.List; import java.util.ArrayList; import java.util.Iterator; import javax.swing.JProgressBar; ///////////////////////////////////////////// // to have this being automatically updating, we'd need to be able to kill off areas // as soon as something changed to a connective line associated with it. class SketchSymbolAreas { // there will be another thread working through this, and more than just these lists List vconncom = new ArrayList(); // these are overlapping groups of componentareas that need to have their symbols laid out all at once List vconncommutual = new ArrayList(); ///////////////////////////////////////////// // make list of areas, and the joined area. // get connective paths to connect to this object ///////////////////////////////////////////// static ConnectiveComponentAreas ccaplaceholder = new ConnectiveComponentAreas(false); static void GetConnCompPath(List lvconnpaths, OnePath op) { // spread through this connected component completely // We used to spread within the sector at each node we meet, // but now we only spread round nodes that only have connective pieces on them. assert op.linestyle == SketchLineStyle.SLS_CONNECTIVE; assert op.pthcca == null; assert lvconnpaths.isEmpty(); List lconnpathsrpstack = new ArrayList(); lconnpathsrpstack.add(new RefPathO(op, false)); // going both directions lconnpathsrpstack.add(new RefPathO(op, true)); lvconnpaths.add(op); RefPathO rpocopy = new RefPathO(); op.pthcca = SketchSymbolAreas.ccaplaceholder; while (!lconnpathsrpstack.isEmpty()) { // scan round and check if this is a fully connective type node RefPathO rpolast = lconnpathsrpstack.remove(lconnpathsrpstack.size() - 1); rpocopy.ccopy(rpolast); do { if ((rpocopy.op.linestyle != SketchLineStyle.SLS_CONNECTIVE) && (rpocopy.op.linestyle != SketchLineStyle.SLS_CENTRELINE)) break; } while (!rpocopy.AdvanceRoundToNode(rpolast)); if (!rpocopy.cequals(rpolast)) continue; // all connective; advance round again and add all these connective edges do { if (rpocopy.op.IsDropdownConnective()) ; else if (rpocopy.op.linestyle == SketchLineStyle.SLS_CENTRELINE) ; else if (rpocopy.op.pthcca == null) { assert !lvconnpaths.contains(rpocopy.op); rpocopy.op.pthcca = SketchSymbolAreas.ccaplaceholder; lconnpathsrpstack.add(new RefPathO(rpocopy.op, !rpocopy.bFore)); lvconnpaths.add(rpocopy.op); } // if we can connect to it, it should be in this list already else { assert rpocopy.op.pthcca == SketchSymbolAreas.ccaplaceholder; assert lvconnpaths.contains(rpocopy.op); } } while (!rpocopy.AdvanceRoundToNode(rpolast)); } assert op.pthcca == SketchSymbolAreas.ccaplaceholder; } ///////////////////////////////////////////// static void GetConnComp(List lvconnpaths, SortedSet lvconnareas, OnePath op, SortedSet Dvsareas) { assert op.linestyle == SketchLineStyle.SLS_CONNECTIVE; assert op.pthcca == null; assert lvconnpaths.isEmpty() && lvconnareas.isEmpty(); GetConnCompPath(lvconnpaths, op); // now we have all the components, we make the set of areas for this component. for (OnePath sop : lvconnpaths) { assert sop.pthcca == SketchSymbolAreas.ccaplaceholder; // was an assignment if ((sop.kaleft != null) && !lvconnareas.contains(sop.kaleft)) // usually such a small set, this should work { //assert Dvsareas.contains(sop.kaleft); // these shouldn't matter as it's just a connective lvconnareas.add(sop.kaleft); } // (both sides should be the same, so this should be unnecessary) if ((sop.karight != null) && !lvconnareas.contains(sop.karight)) { //assert Dvsareas.contains(sop.karight); lvconnareas.add(sop.karight); } } for (OneSArea Dosa : lvconnareas) assert Dvsareas.contains(Dosa); // check } ///////////////////////////////////////////// void MakeConnectiveComponents(List vpaths, SortedSet Dvsareas) { List lvconnpaths = new ArrayList(); List lvconnpathsrem = new ArrayList(); SortedSet lvconnareas = new TreeSet(); for (OnePath op : vpaths) { assert op.pthcca != SketchSymbolAreas.ccaplaceholder; if (op.linestyle != SketchLineStyle.SLS_CONNECTIVE) continue; if (op.pthcca != null) continue; if (op.IsDropdownConnective()) continue; if (op.vpsymbols.isEmpty()) continue; // vpsymbols is actual symbols from fontcolours; plabedl.vlabsymb would be about symbols requested // if (!((op.linestyle == SketchLineStyle.SLS_CONNECTIVE) && (op.pthcca == null) && !op.IsDropdownConnective() && !op.vpsymbols.isEmpty())) // continue; GetConnComp(lvconnpaths, lvconnareas, op, Dvsareas); /*for (OnePath Dop : lvconnpaths) assert vpaths.contains(Dop); // check for (OneSArea Dosa : lvconnareas) assert Dvsareas.contains(Dosa); // check */ // remove connected paths that don't have any symbols on them for (int j = lvconnpaths.size() - 1; j >= 0; j--) { OnePath opj = lvconnpaths.get(j); if (opj.vpsymbols.isEmpty()) { assert opj.pthcca == SketchSymbolAreas.ccaplaceholder; opj.pthcca = null; OnePath lop = lvconnpaths.remove(lvconnpaths.size() - 1); // copy last element into deleted element slot if (j != lvconnpaths.size()) lvconnpaths.set(j, lop); lvconnpathsrem.add(opj); } } // find or make component with this set of areas ConnectiveComponentAreas mcca = null; for (ConnectiveComponentAreas lmcca : vconncom) { if ((lmcca.vconnareas.size() == lvconnareas.size()) && lmcca.vconnareas.containsAll(lvconnareas)) { mcca = lmcca; break; } } if (mcca == null) { mcca = new ConnectiveComponentAreas(lvconnpaths, lvconnpathsrem, lvconnareas); vconncom.add(mcca); } else { mcca.vconnpaths.addAll(lvconnpaths); mcca.vconnpathsrem.addAll(lvconnpathsrem); } // copy in all the pthcca values for (OnePath sop : lvconnpaths) { assert sop.pthcca == SketchSymbolAreas.ccaplaceholder; sop.pthcca = mcca; } lvconnpaths.clear(); lvconnpathsrem.clear(); lvconnareas.clear(); } } ///////////////////////////////////////////// void CollectMutuallyOverlappingComponents() { assert vconncommutual.isEmpty(); List ccastack = new ArrayList(); int Dconmtotal = 0; int Damtotal = 0; for (ConnectiveComponentAreas cca : vconncom) { if (cca.pvconncommutual != null) continue; assert ccastack.isEmpty(); ccastack.add(cca); MutualComponentArea conncommutual = new MutualComponentArea(); while (!ccastack.isEmpty()) { ConnectiveComponentAreas scca = ccastack.remove(ccastack.size() - 1); if (scca.pvconncommutual == null) { conncommutual.MergeIn(scca); for (ConnectiveComponentAreas occa : scca.overlapcomp) { if (occa.pvconncommutual == null) ccastack.add(occa); else assert (occa.pvconncommutual == conncommutual); } } else assert (scca.pvconncommutual == conncommutual); } Dconmtotal += conncommutual.ccamutual.size(); Damtotal += conncommutual.osamutual.size(); // won't exceed number of areas since each is in one mutual only. vconncommutual.add(conncommutual); } assert Dconmtotal == vconncom.size(); } ///////////////////////////////////////////// void CollectOverlappingComponents() { // find overlapping components for (int i = 0; i < vconncom.size(); i++) // had used iterators, but they're not copyable { ConnectiveComponentAreas cca = vconncom.get(i); cca.overlapcomp.add(cca); // always overlaps with self for (int j = i + 1; j < vconncom.size(); j++) { ConnectiveComponentAreas cca1 = vconncom.get(j); if (cca.Overlaps(cca1)) { cca.overlapcomp.add(cca1); cca1.overlapcomp.add(cca); } } } } ///////////////////////////////////////////// // (re)make all the connected symbol areas void MakeSSA(List vpaths, SortedSet vsareas) { // reset everything for (OnePath op : vpaths) op.pthcca = null; for (OneSArea osa : vsareas) osa.ccalist.clear(); vconncom.clear(); vconncommutual.clear(); MakeConnectiveComponents(vpaths, vsareas); CollectOverlappingComponents(); CollectMutuallyOverlappingComponents(); TN.emitMessage("connective compnents: " + vconncom.size() + " mutuals: " + vconncommutual.size()); //for (ConnectiveComponentAreas cca : vconncom) // TN.emitMessage("compnents overlap: " + cca.overlapcomp.size()); } } ///////////////////////////////////////////// ///////////////////////////////////////////// class SymbolLayoutProcess { MainBox mainbox; static int TNnumberofthreads = 4; Thread[] slpthreads = null; MutualComponentAreaScratch[] mcascratches = null; // defer build JProgressBar visiprogressbar; List lvconncommutual; int ivconncommutual; int nactivethreads = 0; // used to tell when we are finishing the final thread boolean bcalculating = false; ///////////////////////////////////////////// SymbolLayoutProcess(MainBox lmainbox) { mainbox = lmainbox; } ///////////////////////////////////////////// class MakeSymbLayoutThread implements Runnable { MutualComponentAreaScratch mcascratch; ///////////////////////////////////////////// MakeSymbLayoutThread(MutualComponentAreaScratch lmcascratch) { mcascratch = lmcascratch; } ///////////////////////////////////////////// // might have two threads going simultaneously public void run() { while (true) { int i = NextMCA(); if (i < 0) { if (i == -2) CleaningUpAfterCalculation(); break; } lvconncommutual.get(i).LayoutMutualSymbols(mcascratch); // all symbols in this batch (sets isymbolstolayout to 2) } } } ///////////////////////////////////////////// synchronized boolean SetupForCalculation() { if (bcalculating) { TN.emitWarning("Still calculating symbol layout -- forcing off"); bcalculating = false; // to force it return false; } bcalculating = true; return true; } ///////////////////////////////////////////// void CleaningUpAfterCalculation() { if (visiprogressbar != null) { visiprogressbar.setValue(0); visiprogressbar.setStringPainted(false); mainbox.sketchdisplay.selectedsubsetstruct.SetSubsetVisibleCodeStringsT(mainbox.sketchdisplay.selectedsubsetstruct.elevset.selevsubset, mainbox.sketchdisplay.sketchgraphicspanel.tsketch); if (lvconncommutual.size() == mainbox.sketchdisplay.sketchgraphicspanel.tsketch.sksya.vconncommutual.size()) mainbox.sketchdisplay.sketchgraphicspanel.SketchChanged(mainbox.sketchdisplay.sketchgraphicspanel.SC_UPDATE_SYMBOLS); mainbox.sketchdisplay.sketchgraphicspanel.RedoBackgroundView(); } bcalculating = false; } ///////////////////////////////////////////// synchronized int NextMCA() { if (ivconncommutual < lvconncommutual.size()) { if (visiprogressbar != null) { visiprogressbar.setValue((ivconncommutual * 100) / lvconncommutual.size()); visiprogressbar.repaint(); if (((ivconncommutual + 10) % 20) == 0) mainbox.sketchdisplay.sketchgraphicspanel.RedoBackgroundView(); } return ivconncommutual++; } nactivethreads--; if (nactivethreads == 0) return -2; return -1; } ///////////////////////////////////////////// void UpdateSymbolLayout(List llvconncommutual, JProgressBar lvisiprogressbar) { if (!SetupForCalculation()) return; lvconncommutual = llvconncommutual; visiprogressbar = lvisiprogressbar; // deferred setup if (slpthreads == null) slpthreads = new Thread[TNnumberofthreads]; if (mcascratches == null) { mcascratches = new MutualComponentAreaScratch[TNnumberofthreads]; for (int i = 0; i < TNnumberofthreads; i++) mcascratches[i] = new MutualComponentAreaScratch(); } visiprogressbar = lvisiprogressbar; llvconncommutual = lvconncommutual; ivconncommutual = 0; // make the threads for (int i = 0; i < TNnumberofthreads; i++) slpthreads[i] = new Thread(new MakeSymbLayoutThread(mcascratches[i])); nactivethreads = TNnumberofthreads; for (int i = 0; i < TNnumberofthreads; i++) slpthreads[i].start(); // wait till all complete if not based on progress bar (ie not triggered by UI) if (lvisiprogressbar == null) { try { for (int i = 0; i < TNnumberofthreads; i++) slpthreads[i].join(); } catch (InterruptedException e) { System.out.print(e); } } } }; tunnelx-20140102.orig/src/OnePath.java0000644000000000000000000011403412261213471014261 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.geom.Line2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.geom.GeneralPath; import java.awt.geom.PathIterator; import java.awt.geom.FlatteningPathIterator; import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.AffineTransform; import java.awt.BasicStroke; import java.awt.Rectangle; import java.awt.Color; import javax.swing.JTextField; import javax.swing.JCheckBox; import java.util.List; import java.util.ArrayList; import java.util.Set; import java.io.IOException; // // // OnePath // // ///////////////////////////////////////////// class OnePath { OnePathNode pnstart; OnePathNode pnend = null; GeneralPath gp = new GeneralPath(); int nlines = 0; String uuid = null; // the tangent angles forwards and backwards. private boolean bpcotangValid = false; private float tanangstart; private float tanangend; private float[] lpco; // the coords of the lines in generalpath float linelength; // control points of spline (used for eval). float[] lpccon = null; // path conditions int linestyle; // see SketchLineStyle. boolean bSplined = false; // actual situation of the generalpath boolean bWantSplined = false; PathLabelDecode plabedl = null; // set of conditions when centreline or connective // links for creating the auto-areas. OnePath aptailleft; // path forward in the right hand polygon boolean baptlfore; // is it forward or backward (useful if path starts and ends at same place). OnePath apforeright; boolean bapfrfore; // links to areas on right and left of this path. OneSArea karight = null; OneSArea kaleft = null; // the area this connective line belongs to ConnectiveComponentAreas pthcca = null; // list of symbols this path contains List vpsymbols = new ArrayList(); // the subsets this path is in (as a string) List vssubsets = new ArrayList(); // Strings (should this be a set?) List vssubsetattrs = new ArrayList(); // SubsetAttr (in parallel) from the current style SubsetAttr subsetattr = null; // one chosen from the vector above boolean bpathvisiblesubset = false; // the tunnel name which we imported this path from String importfromname = null; // value set by other weighting operations for previewing // Color zaltcol = null; // used in quality drawing to help with white outlines, 0 if untouched, 1 if white outline, 2 if counted, 3 if rendered int ciHasrendered = 0; // used for refering the the path in SVG files int svgid = -1; static boolean bHideSplines = false; // set from miHideSplines // allow for the tilted version of each general path in 3D GeneralPath gpzsliced = null; GeneralPath gptiltin = null; GeneralPath gptiltout = null; ///////////////////////////////////////////// // could in future replace sketchframedef with the submapping // and have a local sub-mapping in the copy of the sketch which we // save to from selected connective paths to help preview what it's // going to look like. Like saving views on the sketch. void SetSubsetAttrs(SubsetAttrStyle sas, SketchFrameDef sketchframedef) { vssubsetattrs.clear(); subsetattr = null; if (sas != null) { // we run through subsets (strings associated with this path), map them through the framedef, // and pick up the last subset that's evident in the style for (String ssubset : vssubsets) { if (sketchframedef != null) { String lssubset = sketchframedef.submapping.get(ssubset); if ((lssubset != null) && !lssubset.equals("")) ssubset = lssubset; } SubsetAttr sa = sas.msubsets.get(ssubset); if (sa != null) { vssubsetattrs.add(sa); subsetattr = sa; } } } // fetch default subset in absence if (subsetattr == null) subsetattr = sas.sadefault; GenerateSymbolsFromPath(); // fetch label font, finding default if no match or unset. if ((plabedl != null) && !plabedl.sfontcode.equals("")) { plabedl.labfontattr = subsetattr.labelfontsmap.get(plabedl.sfontcode); if (plabedl.labfontattr == null) { //TN.emitWarning("missing fontlabel " + plabedl.sfontcode + " in SubsetAttrStyle " + subsetattr.subsetname); plabedl.labfontattr = subsetattr.labelfontsmap.get("default"); } } } ///////////////////////////////////////////// boolean AreaBoundingType() { return ((nlines != 0) && (linestyle != SketchLineStyle.SLS_CENTRELINE) && (linestyle != SketchLineStyle.SLS_CONNECTIVE) /*&& (linestyle != SketchLineStyle.SLS_CEILINGBOUND)*/); // had taken out filled types, but this broke one of the symbol areas. } ///////////////////////////////////////////// boolean IsDropdownConnective() { return ((linestyle == SketchLineStyle.SLS_CONNECTIVE) && (plabedl != null) && (plabedl.barea_pres_signal == SketchLineStyle.ASE_HCOINCIDE)); } ///////////////////////////////////////////// boolean IsZSetNodeConnective() { return ((linestyle == SketchLineStyle.SLS_CONNECTIVE) && (plabedl != null) && (plabedl.barea_pres_signal == SketchLineStyle.ASE_ZSETRELATIVE)); } ///////////////////////////////////////////// boolean IsSketchFrameConnective() { if (!((linestyle == SketchLineStyle.SLS_CONNECTIVE) && (plabedl != null) && (plabedl.barea_pres_signal == SketchLineStyle.ASE_SKETCHFRAME))) return false; assert (plabedl.sketchframedef != null); return true; } ///////////////////////////////////////////// boolean IsSurvexLabel() { return ((linestyle == SketchLineStyle.SLS_CONNECTIVE) && (plabedl != null) && plabedl.sfontcode.equals("survey")); } ///////////////////////////////////////////// boolean IsElevationPath() { return ((linestyle == SketchLineStyle.SLS_CONNECTIVE) && (plabedl != null) && (plabedl.barea_pres_signal == SketchLineStyle.ASE_ELEVATIONPATH)); } ///////////////////////////////////////////// boolean IsElevationCentreline() { return ((linestyle == SketchLineStyle.SLS_CENTRELINE) && (plabedl != null) && (plabedl.centrelineelev != null)); } ///////////////////////////////////////////// private void Update_pco() { // first update the pco list lpco = new float[nlines * 2 + 2]; float[] coords = new float[6]; PathIterator pi = gp.getPathIterator(null); if (pi.currentSegment(coords) != PathIterator.SEG_MOVETO) TN.emitProgError("move to not first"); // put in the moveto. lpco[0] = coords[0]; lpco[1] = coords[1]; pi.next(); for (int i = 0; i < nlines; i++) { if (pi.isDone()) TN.emitProgError("done before end"); int curvtype = pi.currentSegment(coords); if (curvtype == PathIterator.SEG_LINETO) { lpco[i * 2 + 2] = coords[0]; lpco[i * 2 + 3] = coords[1]; } else if (curvtype == PathIterator.SEG_QUADTO) TN.emitProgError("No quadric segments"); else if (curvtype == PathIterator.SEG_CUBICTO) { lpco[i * 2 + 2] = coords[4]; lpco[i * 2 + 3] = coords[5]; } else TN.emitProgError("not lineto"); pi.next(); } if (!pi.isDone()) TN.emitProgError("not done at end"); // set the caching flag SetTangentAngles(); bpcotangValid = true; lpccon = null; if (bSplined) BuildSplineContolPoints(); } ///////////////////////////////////////////// private void SetTangentAngles() { // now do the tangent angles at the endpoints if (nlines >= 1) { tanangstart = (float)Vec3.Arg(lpco[2] - lpco[0], lpco[3] - lpco[1]); tanangend = (float)Vec3.Arg(lpco[nlines * 2 - 2] - lpco[nlines * 2], lpco[nlines * 2 - 1] - lpco[nlines * 2 + 1]); } // newly added lengths here. linelength = 0.0F; for (int i = 1; i <= nlines; i++) { float vx = lpco[i * 2] - lpco[i * 2 - 2]; float vy = lpco[i * 2 + 1] - lpco[i * 2 - 1]; linelength += (float)Math.sqrt(vx * vx + vy * vy); } } ///////////////////////////////////////////// float[] GetCoords() { if (!bpcotangValid) Update_pco(); return lpco; } ///////////////////////////////////////////// static Point2D segpt = new Point2D.Double(); double MeasureSegmentLength(int i) { if (!bSplined) { double vx = (lpco[i * 2 + 2] - lpco[i * 2]); double vy = (lpco[i * 2 + 3] - lpco[i * 2 + 1]); return Math.sqrt(vx * vx + vy * vy); } double prevx = lpco[i * 2]; double prevy = lpco[i * 2 + 1]; int nsegs = 5; double res = 0.0; for (int j = 1; j <= nsegs; j++) { double vx, vy; if (j < nsegs) { EvalSeg(segpt, null, i, (double)j / nsegs); vx = segpt.getX() - prevx; vy = segpt.getY() - prevy; prevx = segpt.getX(); prevy = segpt.getY(); } else { vx = lpco[i * 2 + 2] - prevx; vy = lpco[i * 2 + 3] - prevy; } res += Math.sqrt(vx * vx + vy * vy); } return res; } ///////////////////////////////////////////// void EvalSeg(Point2D res, Point2D tan, int i, double tr) { // line type straightforward if (!bSplined) { if (res != null) res.setLocation(lpco[i * 2] * (1.0 - tr) + lpco[i * 2 + 2] * tr, lpco[i * 2 + 1] * (1.0 - tr) + lpco[i * 2 + 3] * tr); if (tan != null) tan.setLocation(lpco[i * 2 + 2] - lpco[i * 2], lpco[i * 2 + 3] - lpco[i * 2 + 1]); return; } // full spline type double trsq = tr * tr; double trcu = trsq * tr; if (res != null) { double lp0 = -trcu + 3 * trsq - 3 * tr + 1.0; double lp1 = 3 * trcu - 6 * trsq + 3 * tr; double lp2 = -3 * trcu + 3 * trsq; double lp3 = trcu; res.setLocation(lpco[i * 2] * lp0 + lpccon[i * 4] * lp1 + lpccon[i * 4 + 2] * lp2 + lpco[i * 2 + 2] * lp3, lpco[i * 2 + 1] * lp0 + lpccon[i * 4 + 1] * lp1 + lpccon[i * 4 + 3] * lp2 + lpco[i * 2 + 3] * lp3); } if (tan != null) { double ltp0 = -3 * trsq + 6 * tr - 3; double ltp1 = 9 * trsq - 12 * tr + 3; double ltp2 = -9 * trsq + 6 * tr; double ltp3 = 3 * trsq; tan.setLocation(lpco[i * 2] * ltp0 + lpccon[i * 4] * ltp1 + lpccon[i * 4 + 2] * ltp2 + lpco[i * 2 + 2] * ltp3, lpco[i * 2 + 1] * ltp0 + lpccon[i * 4 + 1] * ltp1 + lpccon[i * 4 + 3] * ltp2 + lpco[i * 2 + 3] * ltp3); } } ///////////////////////////////////////////// void Eval(Point2D res, Point2D tan, double t) { if (!bpcotangValid) TN.emitProgError("not synched pco"); int i = (int)t; if (i == nlines) i--; double tr = t - i; EvalSeg(res, tan, i, tr); } ///////////////////////////////////////////// OnePath FuseNode(OnePathNode pnconnect, OnePath op2) { boolean breflect1 = (pnconnect != pnend); boolean breflect2 = (pnconnect != op2.pnstart); // make the new path OnePath respath = new OnePath(breflect1 ? pnend : pnstart); respath.linestyle = linestyle; float[] pco = GetCoords(); for (int i = 1; i < nlines; i++) { int ir = (breflect1 ? nlines - i : i); respath.LineTo(pco[ir * 2 + 0], pco[ir * 2 + 1]); } float[] pco2 = op2.GetCoords(); for (int i = 0; i < op2.nlines; i++) { int ir = (breflect2 ? op2.nlines - i : i); respath.LineTo(pco2[ir * 2 + 0], pco2[ir * 2 + 1]); } respath.EndPath(breflect2 ? op2.pnstart : op2.pnend); respath.bWantSplined = (op2.bSplined && op2.bSplined); if (respath.bWantSplined && !OnePath.bHideSplines) respath.Spline(respath.bWantSplined, false); return respath; } ///////////////////////////////////////////// static Point2D cpres = new Point2D.Double(); static Point2D cptan = new Point2D.Double(); double ClosestPoint(double ptx, double pty, double scale) { GetCoords(); // find closest node within the scale, so we favour splitting at one of them rather than just to the side int ilam = -1; double scalesq = (scale != -1.0 ? scale * scale : -1.0); double distsq = scalesq; if (scale != -1.0) { for (int i = 0; i <= nlines; i++) { double pvx = ptx - lpco[i * 2]; double pvy = pty - lpco[i * 2 + 1]; double pvsq = pvx * pvx + pvy * pvy; if ((distsq == -1.0) || (pvsq < distsq)) { ilam = i; distsq = pvsq; } } if (ilam != -1) return ilam; } // not on node. Find closest line. double lam = -1.0; for (int i = 0; i < nlines; i++) { double vx = lpco[i * 2 + 2] - lpco[i * 2]; double vy = lpco[i * 2 + 3] - lpco[i * 2 + 1]; double pvx = ptx - lpco[i * 2]; double pvy = pty - lpco[i * 2 + 1]; double vsq = vx * vx + vy * vy; double pdv = vx * pvx + vy * pvy; double llam = Math.min(1.0F, Math.max(0.0F, (vsq == 0.0F ? 0.5F : pdv / vsq))); double nptx = vx * llam - pvx; double npty = vy * llam - pvy; double dnptsq = nptx * nptx + npty * npty; if ((i == 0) || (dnptsq < distsq)) { ilam = i; lam = llam; distsq = dnptsq; } } // if this is non-splined, we have an answer if (!bSplined) return ((((lam > 0.0) && (lam < 1.0) && (distsq < scalesq)) || (scale == -1.0)) ? ilam + lam : -1.0); // splined case; we look for a close evaluation. hunt by rhapson. for (int j = 0; j < 3; j++) { Eval(cpres, cptan, ilam + lam); double pvx = ptx - cpres.getX(); double pvy = pty - cpres.getY(); distsq = pvx * pvx + pvy * pvy; double pdt = pvx * cptan.getX() + pvy * cptan.getY(); double tansq = cptan.getX() * cptan.getX() + cptan.getY() * cptan.getY(); double h = (tansq != 0.0 ? pdt / tansq : 0.0); System.out.println("iter " + distsq + " " + h); lam += h; if (lam < 0.0) { ilam--; lam += 1.0; if ((ilam < 0) || (lam < 0.0)) return -1.0; } if (lam >= 1.0) { ilam++; lam += 1.0; if ((ilam > nlines) || (lam >= 1.0)) return -1.0; } } // return the value if we are within the scale distance return (((scale == -1.0) || (distsq < scalesq)) ? (ilam + lam) : -1.0); } ///////////////////////////////////////////// // needs to be used by fusetranslate and reflectcurrent to be more correct regarding undos etc // also should be used by split at node void CopyPathAttributes(OnePath op) // used by fuse and import sketch { // copy over values. linestyle = op.linestyle; bWantSplined = op.bWantSplined; if (bWantSplined && !OnePath.bHideSplines) Spline(bWantSplined, false); if (op.plabedl != null) plabedl = new PathLabelDecode(op.plabedl); assert vssubsets.isEmpty() && vssubsetattrs.isEmpty(); vssubsets.addAll(op.vssubsets); vssubsetattrs.addAll(op.vssubsetattrs); bpathvisiblesubset = op.bpathvisiblesubset; importfromname = op.importfromname; } ///////////////////////////////////////////// void MakeZsliced(double zlo, double zhi) { double z0 = pnstart.zalt; double z1 = pnend.zalt; boolean ballin = ((zlo <= z0) && (z0 <= zhi) && (zlo <= z1) && (z1 <= zhi)); boolean ballout = (((z0 < zlo) && (z1 < zlo)) || ((z0 > zhi) && (z1 > zhi))); if (ballout || ballin || (nlines == 0)) { gpzsliced = (ballout ? null : gp); return; } if ((gpzsliced == null) || (gpzsliced == gp)) gpzsliced = new GeneralPath(); else gpzsliced.reset(); float[] pco = GetCoords(); int prevoutcode = 0; double prevz = 0.0; double prevtiltx = 0.0; double prevtilty = 0.0; for (int i = 0; i <= nlines; i++) { double lam = i * 1.0 / nlines; // maybe by along projection, unless ends are close together like it's a loop double z = z0 * (1.0 - lam) + z1 * lam; double tiltx = pco[i * 2]; double tilty = pco[i * 2 + 1]; int outcode = (z < zlo ? -1 : (z > zhi ? 1 : 0)); if (i != 0) { while (prevoutcode != outcode) { double cz = (((prevoutcode == -1) || (outcode == -1)) ? zlo : zhi); double clam = (cz - prevz) / (z - prevz); double ctiltx = prevtiltx * (1.0 - clam) + tiltx * clam; double ctilty = prevtilty * (1.0 - clam) + tilty * clam; if (prevoutcode == 0) gpzsliced.lineTo(ctiltx, ctilty); prevoutcode += (prevoutcode < outcode ? 1 : -1); if (prevoutcode == 0) gpzsliced.moveTo(ctiltx, ctilty); } if (outcode == 0) gpzsliced.lineTo(tiltx, tilty); } else if (outcode == 0) gpzsliced.moveTo(tiltx, tilty); prevtiltx = tiltx; prevtilty = tilty; prevz = z; prevoutcode = outcode; } } ///////////////////////////////////////////// void MakeTilted(double zlo, double zhi, double scaTiltZ, AffineTransform currtrans) { if (nlines == 0) return; assert zlo < zhi; double z0 = pnstart.zalt; double z1 = pnend.zalt; boolean ballin = ((zlo <= z0) && (z0 <= zhi) && (zlo <= z1) && (z1 <= zhi)); boolean ballout = (((z0 < zlo) && (z1 < zlo)) || ((z0 > zhi) && (z1 > zhi))); if (ballin) gptiltout = null; else if (gptiltout == null) gptiltout = new GeneralPath(); else gptiltout.reset(); if (ballout) gptiltin = null; else if (gptiltin == null) gptiltin = new GeneralPath(); else gptiltin.reset(); float[] pco = GetCoords(); float[] pcoT = new float[pco.length]; currtrans.transform(pco, 0, pcoT, 0, nlines+1); int prevoutcode = 0; double prevz = 0.0; double prevtiltx = 0.0; double prevtilty = 0.0; for (int i = 0; i <= nlines; i++) { double lam = i * 1.0 / nlines; // maybe by along projection, unless ends are close together like it's a loop double z = z0 * (1.0 - lam) + z1 * lam; double tiltx = pcoT[i * 2]; double tilty = pcoT[i * 2 + 1] - (z - zlo) * scaTiltZ; int outcode = (z < zlo ? -1 : (z > zhi ? 1 : 0)); if (i != 0) { while (prevoutcode != outcode) { double cz = (((prevoutcode == -1) || (outcode == -1)) ? zlo : zhi); double clam = (cz - prevz) / (z - prevz); double ctiltx = prevtiltx * (1.0 - clam) + tiltx * clam; double ctilty = prevtilty * (1.0 - clam) + tilty * clam; (prevoutcode == 0 ? gptiltin : gptiltout).lineTo(ctiltx, ctilty); prevoutcode += (prevoutcode < outcode ? 1 : -1); (prevoutcode == 0 ? gptiltin : gptiltout).moveTo(ctiltx, ctilty); } (outcode == 0 ? gptiltin : gptiltout).lineTo(tiltx, tilty); } else (outcode == 0 ? gptiltin : gptiltout).moveTo(tiltx, tilty); prevtiltx = tiltx; prevtilty = tilty; prevz = z; prevoutcode = outcode; } } ///////////////////////////////////////////// void Spline(boolean lbSplined, boolean bReflect) { if (nlines == 0) return; // could search out paths on other sides of the nodes and make things tangent to them. // somehow kill segments that are too short. float[] pco = GetCoords(); bSplined = lbSplined; if (bReflect) { for (int i = 0; i <= nlines / 2; i++) { int ir = nlines - i; float t0 = pco[i * 2 + 0]; float t1 = pco[i * 2 + 1]; pco[i * 2 + 0] = pco[ir * 2 + 0]; pco[i * 2 + 1] = pco[ir * 2 + 1]; pco[ir * 2 + 0] = t0; pco[ir * 2 + 1] = t1; } lpccon = null; } if (lpccon == null) BuildSplineContolPoints(); LoadFromCoords(); SetTangentAngles(); // these need resetting } ///////////////////////////////////////////// private void BuildSplineContolPoints() { lpccon = new float[nlines * 4]; // Make a tangent at each node. float ptanx = -99999; float ptany = -99999; // the before point and the off end point. float xm1; float ym1; if (pnstart == pnend) // single loop type { xm1 = lpco[(nlines - 1) * 2]; ym1 = lpco[(nlines - 1) * 2 + 1]; } else // in the future we'll search for the the best continuation. { xm1 = lpco[0]; ym1 = lpco[1]; } float xp1; float yp1; if (pnstart == pnend) // single loop type { xp1 = lpco[2]; yp1 = lpco[3]; } else // in the future we'll search for the the best continuation. { xp1 = lpco[nlines * 2]; yp1 = lpco[nlines * 2 + 1]; } // put in all the segments. for (int i = 0; i <= nlines; i++) { //TN.emitMessage("node " + String.valueOf(i)); int ip = Math.max(0, i - 1); int in = Math.min(nlines, i + 1); float xv0 = lpco[i * 2] - (i != 0 ? lpco[(i - 1) * 2] : xm1); float yv0 = lpco[i * 2 + 1] - (i != 0 ? lpco[(i - 1) * 2 + 1] : ym1); float xv1 = (i != nlines ? lpco[(i + 1) * 2] : xp1) - lpco[i * 2]; float yv1 = (i != nlines ? lpco[(i + 1) * 2 + 1] : yp1) - lpco[i * 2 + 1]; float v0len = (float)Math.sqrt(xv0 * xv0 + yv0 * yv0); float v1len = (float)Math.sqrt(xv1 * xv1 + yv1 * yv1); if (v0len == 0.0F) v0len = 1.0F; if (v1len == 0.0F) v1len = 1.0F; float ntanx = xv0 / v0len + xv1 / v1len; float ntany = yv0 / v0len + yv1 / v1len; //TN.emitMessage("tan " + String.valueOf(ntanx) + ", " + String.valueOf(ntany)); // put in the line to this point if (i != 0) { float tfac = Math.min(5.0F, v0len / 4.0F); lpccon[(i - 1) * 4] = lpco[(i - 1) * 2] + ptanx * tfac; lpccon[(i - 1) * 4 + 1] = lpco[(i - 1) * 2 + 1] + ptany * tfac; lpccon[(i - 1) * 4 + 2] = lpco[i * 2] - ntanx * tfac; lpccon[(i - 1) * 4 + 3] = lpco[i * 2 + 1] - ntany * tfac; } ptanx = ntanx; ptany = ntany; } } ///////////////////////////////////////////// void LoadFromCoords() { gp.reset(); gp.moveTo(lpco[0], lpco[1]); // non-splined if (!bSplined) { for (int i = 1; i <= nlines; i++) gp.lineTo(lpco[i * 2], lpco[i * 2 + 1]); } // splined else { for (int i = 1; i <= nlines; i++) gp.curveTo(lpccon[(i - 1) * 4], lpccon[(i - 1) * 4 + 1], lpccon[(i - 1) * 4 + 2], lpccon[(i - 1) * 4 + 3], lpco[i * 2], lpco[i * 2 + 1]); } } ///////////////////////////////////////////// void UpdateStationLabelsFromCentreline() { assert (linestyle == SketchLineStyle.SLS_CENTRELINE); assert (plabedl != null); if (!plabedl.IsCentrelineType()) return; String pnlabtail = plabedl.centrelinetail; String pnlabhead = plabedl.centrelinehead; // put the station labels in . format. pnlabtail.replace('|', '.'); pnlabtail.replace('^', '.'); pnlabhead.replace('|', '.'); pnlabhead.replace('^', '.'); // these warnings are firing because we have vertical legs. if ((pnstart.pnstationlabel != null) && !pnstart.pnstationlabel.equals(pnlabtail)) TN.emitWarning("Mismatch label station tail: " + pnlabtail + " " + (pnstart.pnstationlabel == null ? "null" : pnstart.pnstationlabel)); pnstart.pnstationlabel = pnlabtail; if ((pnend.pnstationlabel != null) && !pnend.pnstationlabel.equals(pnlabhead)) TN.emitWarning("Mismatch label station head: " + pnlabhead + " " + (pnend.pnstationlabel == null ? "null" : pnend.pnstationlabel)); pnend.pnstationlabel = pnlabhead; } // joinpath. // warp to endpoints. ///////////////////////////////////////////// void WriteXMLpath(LineOutputStream los, int ind0, int ind1, int indent) throws IOException { // we should be able to work out automatically which attributes are not necessary by keeping a stack, but not for now. if (bWantSplined) los.WriteLine(TNXML.xcomopen(indent, TNXML.sSKETCH_PATH, TNXML.sFROM_SKNODE, String.valueOf(ind0), TNXML.sTO_SKNODE, String.valueOf(ind1), TNXML.sSK_LINESTYLE, TNXML.EncodeLinestyle(linestyle), TNXML.sSPLINED, (bWantSplined ? "1" : "0"))); else los.WriteLine(TNXML.xcomopen(indent, TNXML.sSKETCH_PATH, TNXML.sFROM_SKNODE, String.valueOf(ind0), TNXML.sTO_SKNODE, String.valueOf(ind1), TNXML.sSK_LINESTYLE, TNXML.EncodeLinestyle(linestyle))); if (plabedl != null) plabedl.WriteXML(los, indent + 1); // sketch subsets for (String ssubset : vssubsets) los.WriteLine(TNXML.xcom(indent + 1, TNXML.sSKSUBSET, TNXML.sSKSNAME, ssubset)); if ((importfromname != null) && (importfromname.length() != 0)) los.WriteLine(TNXML.xcom(indent + 1, TNXML.sSKIMPORTFROM, TNXML.sSKSNAME, importfromname)); // write the pieces. float[] pco = GetCoords(); // not spline (respline on loading). // first point if (pnstart.IsCentrelineNode()) los.WriteLine(TNXML.xcom(indent + 1, TNXML.sPOINT, TNXML.sPTX, String.valueOf(pco[0]), TNXML.sPTY, String.valueOf(pco[1]), TNXML.sPTZ, String.valueOf(pnstart.zalt))); else los.WriteLine(TNXML.xcom(indent + 1, TNXML.sPOINT, TNXML.sPTX, String.valueOf(pco[0]), TNXML.sPTY, String.valueOf(pco[1]))); // middle points for (int i = 1; i < nlines; i++) los.WriteLine(TNXML.xcom(indent + 1, TNXML.sPOINT, TNXML.sPTX, String.valueOf(pco[i * 2]), TNXML.sPTY, String.valueOf(pco[i * 2 + 1]))); // end point (this may be a repeat of the first point (in case of a vertical surveyline). if (pnend.IsCentrelineNode()) los.WriteLine(TNXML.xcom(indent + 1, TNXML.sPOINT, TNXML.sPTX, String.valueOf(pco[nlines * 2]), TNXML.sPTY, String.valueOf(pco[nlines * 2 + 1]), TNXML.sPTZ, String.valueOf(pnend.zalt))); else los.WriteLine(TNXML.xcom(indent + 1, TNXML.sPOINT, TNXML.sPTX, String.valueOf(pco[nlines * 2]), TNXML.sPTY, String.valueOf(pco[nlines * 2 + 1]))); los.WriteLine(TNXML.xcomclose(indent, TNXML.sSKETCH_PATH)); } ///////////////////////////////////////////// // pull out the rsymbol things void GenerateSymbolsFromPath() { vpsymbols.clear(); if ((plabedl == null) || plabedl.vlabsymb.isEmpty()) return; for (String rname : plabedl.vlabsymb) { SymbolStyleAttr ssa = subsetattr.subautsymbolsmap.get(rname); if (ssa == null) continue; // this stuff should go... float[] pco = GetCoords(); // now build the symbols defined by the aut-symbol. for (SSymbolBase ssb : ssa.ssymbolbs) { OneSSymbol oss = new OneSSymbol(pco, nlines, 0.0F, ssb, this); oss.RefreshSymbol(); vpsymbols.add(oss); } } } ///////////////////////////////////////////// void paintLabel(GraphicsAbstraction ga, Color col) { // labfontattr is not set for symbol paths at the moment if ((plabedl.labfontattr != null) && (plabedl.labfontattr.labelcolour == null)) return; // over-ridden example. if ((plabedl.drawlab == null) || (plabedl.drawlab.length() == 0)) return; plabedl.UpdateLabel((float)pnstart.pn.getX(), (float)pnstart.pn.getY(), (float)pnend.pn.getX(), (float)pnend.pn.getY()); ga.drawlabel(plabedl, (float)pnstart.pn.getX(), (float)pnstart.pn.getY(), col); } ///////////////////////////////////////////// // takes in the active flag to draw outline on filled things void paintWquality(GraphicsAbstraction ga) { // non-drawable if ((linestyle == SketchLineStyle.SLS_INVISIBLE) || (linestyle == SketchLineStyle.SLS_CONNECTIVE)) return; if (subsetattr.linestyleattrs[linestyle] == null) { TN.emitMessage("subset linestyle attr for " + linestyle + " missing for "+ subsetattr.subsetname); return; } if (subsetattr.linestyleattrs[linestyle].strokecolour == null) return; // hidden Color col = null; if (SketchLineStyle.bDepthColours) col = SketchLineStyle.GetColourFromCollam((pnstart.icollam + pnend.icollam) / 2, false); if (SketchLineStyle.bPathSubsetColours) col = (vssubsetattrs.size() != 0 ? vssubsetattrs.get(0).areacolour.darker() : null); ga.drawPath(this, subsetattr.linestyleattrs[linestyle], col); } ///////////////////////////////////////////// void paintPitchBoundDash(GraphicsAbstraction ga) { PathIterator pi = gp.getPathIterator(null); if (pi.currentSegment(moucoords) != PathIterator.SEG_MOVETO) return; float x0 = moucoords[0]; float y0 = moucoords[1]; pi.next(); if (pi.isDone()) return; int curvtype = pi.currentSegment(moucoords); //if (curvtype != PathIterator.SEG_LINETO) float x1 = moucoords[0]; float y1 = moucoords[1]; float xv = x1 - x0; float yv = y1 - y0; float vlen = (float)Math.sqrt(xv * xv + yv * yv); if (vlen == 0.0F) return; mouperplin.setLine(x1, y1, x1 - yv * SketchLineStyle.mouperplinlength / vlen, y1 + xv * SketchLineStyle.mouperplinlength / vlen); ga.drawShape(mouperplin, SketchLineStyle.ActiveLineStyleAttrs[SketchLineStyle.SLS_DETAIL]); } ///////////////////////////////////////////// void paintNodes(GraphicsAbstraction ga) { float[] pco = GetCoords(); for (int i = 1; i < nlines; i++) { float sx = pco[i * 2]; float sy = pco[i * 2 + 1]; mouperplin.setLine(sx, sy, sx, sy + SketchLineStyle.mouperplinlength); ga.drawShape(mouperplin, SketchLineStyle.ActiveLineStyleAttrs[SketchLineStyle.SLS_CENTRELINE]); } } static Color colshadr = new Color(0.0F, 0.7F, 0.2F, 0.25F); static Color colshadl = new Color(0.3F, 0.7F, 0.0F, 0.25F); static Line2D.Float mouperplin = new Line2D.Float(); void paintW(GraphicsAbstraction ga, boolean bisSubsetted, boolean bSActive) { LineStyleAttr linestyleattr; // set the colour and style -- we've had to add some overloading for the numerous subtypes of connective line if (bSActive) { linestyleattr = SketchLineStyle.ActiveLineStyleAttrs[linestyle]; if (linestyle == SketchLineStyle.SLS_CONNECTIVE) { if (IsElevationPath()) linestyleattr = SketchLineStyle.ActiveLineStyleAttrsConnective[SketchLineStyle.ASE_ELEVATIONPATH]; } } else if (bisSubsetted) { linestyleattr = SketchLineStyle.inSelSubsetLineStyleAttrs[linestyle]; if (linestyle == SketchLineStyle.SLS_CONNECTIVE) { if (IsElevationPath()) linestyleattr = SketchLineStyle.inSelSubsetLineStyleAttrsConnective[SketchLineStyle.ASE_ELEVATIONPATH]; } } else linestyleattr = SketchLineStyle.notInSelSubsetLineStyleAttrs[linestyle]; Color col; if (SketchLineStyle.bDepthColours && !bSActive) col = SketchLineStyle.GetColourFromCollam((pnstart.icollam + pnend.icollam) / 2, false); else col = linestyleattr.strokecolour; ga.drawPath(this, linestyleattr, col); // the text (which is drawlab) if ((linestyle == SketchLineStyle.SLS_CONNECTIVE) && (plabedl != null)) { if (plabedl.labfontattr != null) paintLabel(ga, col); } // a side dash for pitch boundaries (could refer to a sketchdisplay.miTransitiveSubset.isSelected() type thing) if (bSActive && ((linestyle == SketchLineStyle.SLS_PITCHBOUND) || (linestyle == SketchLineStyle.SLS_CEILINGBOUND))) paintPitchBoundDash(ga); if (IsElevationCentreline()) paintNodes(ga); } void paintWzthinned(GraphicsAbstraction ga, boolean bisSubsetted) { LineStyleAttr linestyleattr = (bisSubsetted ? SketchLineStyle.inSelSubsetLineStyleAttrs[linestyle] : SketchLineStyle.notInSelSubsetLineStyleAttrs[linestyle]); Color col = (SketchLineStyle.bDepthColours ? SketchLineStyle.GetColourFromCollam((pnstart.icollam + pnend.icollam) / 2, false) : linestyleattr.strokecolour); ga.drawPathzthinned(this, linestyleattr, col); // the text (which is drawlab) if ((linestyle == SketchLineStyle.SLS_CONNECTIVE) && (plabedl != null)) { if (plabedl.labfontattr != null) paintLabel(ga, col); } // the text (which is drawlab) [ should depend on the end node z ] /*if ((linestyle == SketchLineStyle.SLS_CONNECTIVE) && (plabedl != null)) { if (plabedl.labfontattr != null) paintLabel(ga, col); }*/ } // check we're drawing correctly. // work out how the ellipse works, and do from endpoints in XC case // make the distorting account for multiple connective lines // deal with importing into another sketch ///////////////////////////////////////////// String toStringCentreline() { assert linestyle == SketchLineStyle.SLS_CENTRELINE; assert plabedl != null; assert (plabedl.centrelinetail != null) && (plabedl.centrelinehead != null); return "tail=" + plabedl.centrelinetail + " head=" + plabedl.centrelinehead; } ///////////////////////////////////////////// static float[] moucoords = new float[6]; void IntermedLines(GeneralPath moupath, int nmoupathpieces) { if (nmoupathpieces == 1) return; PathIterator pi = moupath.getPathIterator(null); if (pi.currentSegment(moucoords) != PathIterator.SEG_MOVETO) { TN.emitProgError("move to not first"); return; } // put in the moveto. pi.next(); for (int i = 1; i < nmoupathpieces; i++) { if (pi.isDone()) { TN.emitProgError("done before end"); return; } int curvtype = pi.currentSegment(moucoords); if (curvtype != PathIterator.SEG_LINETO) { TN.emitProgError("not lineto"); return; } LineTo(moucoords[0], moucoords[1]); pi.next(); } if (pi.currentSegment(moucoords) != PathIterator.SEG_LINETO) { TN.emitProgError("last straight motion missing"); return; } pi.next(); if (!pi.isDone()) { TN.emitProgError("not done at end Intermedlines"); return; } } ///////////////////////////////////////////// void LineTo(float x, float y) { bpcotangValid = false; gp.lineTo(x, y); nlines++; } ///////////////////////////////////////////// Point2D BackOne() { bpcotangValid = false; int Nnlines = nlines - 1; assert (Nnlines >= 0); // fairly desperate measures here. almost worth making a new genpath and iterating through it. float[] pco = GetCoords(); gp.reset(); nlines = 0; gp.moveTo((float)pnstart.pn.getX(), (float)pnstart.pn.getY()); for (int i = 0; i < Nnlines; i++) LineTo(pco[i * 2 + 2], pco[i * 2 + 3]); return gp.getCurrentPoint(); } ///////////////////////////////////////////// boolean EndPath(OnePathNode lpnend) { bpcotangValid = false; if (lpnend == null) { if (nlines == 0) return false; Point2D pcp = gp.getCurrentPoint(); pnend = new OnePathNode((float)pcp.getX(), (float)pcp.getY(), 0.0F); System.out.println("makingnew onepathnode thing zzzzz"); // consider inlining to use benefits of GetMidZsel() } else { Point2D pcp = gp.getCurrentPoint(); pnend = lpnend; if (((float)pcp.getX() != (float)pnend.pn.getX()) || ((float)pcp.getY() != (float)pnend.pn.getY())) LineTo((float)pnend.pn.getX(), (float)pnend.pn.getY()); } GetCoords(); if (bWantSplined && !OnePath.bHideSplines) Spline(bWantSplined, false); return true; } ///////////////////////////////////////////// OnePath() { } ///////////////////////////////////////////// OnePath(OnePathNode lpnstart) { bpcotangValid = false; pnstart = lpnstart; gp.moveTo((float)pnstart.pn.getX(), (float)pnstart.pn.getY()); } ///////////////////////////////////////////// // making centreline types OnePath(OnePathNode lpnstart, String ltail, OnePathNode lpnend, String lhead) { bpcotangValid = false; linestyle = SketchLineStyle.SLS_CENTRELINE; pnstart = lpnstart; gp.moveTo((float)pnstart.pn.getX(), (float)pnstart.pn.getY()); // this is the EndPath function, making sure that zero length centrelines still have two endpoints. pnend = lpnend; LineTo((float)pnend.pn.getX(), (float)pnend.pn.getY()); plabedl = new PathLabelDecode(); // centreline type (very clear) plabedl.centrelinetail = ltail; plabedl.centrelinehead = lhead; // set the original length (which never gets updated) GetCoords(); } ///////////////////////////////////////////// Rectangle2D getBounds(AffineTransform currtrans) { Rectangle2D res; if (currtrans != null) { // looks pretty horrid way to do it. GeneralPath lgp = (GeneralPath)gp.clone(); lgp.transform(currtrans); res = lgp.getBounds2D(); } else res = gp.getBounds2D(); if ((plabedl != null) && (plabedl.vdrawlablns.size() != 0)) { for (PathLabelElement ple : plabedl.vdrawlablns) { if (currtrans != null) { Rectangle2D ltr = (Rectangle2D)ple.textrect.clone(); // ltr.transform(currtrans); TN.emitWarning("Not finnished getBounds in OnePath"); res.add(ltr); } else res.add(ple.textrect); } } return res; } ///////////////////////////////////////////// float GetTangent(boolean bForward) { if (!bpcotangValid) Update_pco(); return(bForward ? tanangstart : tanangend); } ///////////////////////////////////////////// // this function is crap format. Used only by OneSArea in LinkArea static float[] CCcoords = new float[6]; void ToCoordsCubic(float[] pco) { assert pco.length >= nlines * 6 + 2; PathIterator pi = gp.getPathIterator(null); int curvtype = pi.currentSegment(CCcoords); assert curvtype == PathIterator.SEG_MOVETO; // put in the moveto. pco[0] = CCcoords[0]; pco[1] = CCcoords[1]; pi.next(); for (int i = 0; i < nlines; i++) { int i6 = i * 6; assert !pi.isDone(); curvtype = pi.currentSegment(CCcoords); if (curvtype == PathIterator.SEG_LINETO) { pco[i6 + 2] = CCcoords[0]; pco[i6 + 3] = CCcoords[1]; pco[i6 + 4] = CCcoords[0]; pco[i6 + 5] = CCcoords[1]; pco[i6 + 6] = CCcoords[0]; pco[i6 + 7] = CCcoords[1]; } else if (curvtype == PathIterator.SEG_CUBICTO) { pco[i6 + 2] = CCcoords[0]; pco[i6 + 3] = CCcoords[1]; pco[i6 + 4] = CCcoords[2]; pco[i6 + 5] = CCcoords[3]; pco[i6 + 6] = CCcoords[4]; pco[i6 + 7] = CCcoords[5]; } else assert false; pi.next(); } assert pi.isDone(); } String svgdvalue(float xoffset, float yoffset) { StringBuffer d = new StringBuffer(); d.append("M" + String.valueOf(lpco[0] + xoffset) + " " + String.valueOf(lpco[1] + yoffset)); for (int i = 1; i <= nlines; i++) { if (bSplined) d.append(" C" + String.valueOf(lpccon[(i - 1) * 4] + xoffset) + " " + String.valueOf(lpccon[(i - 1) * 4 + 1] + yoffset) + " " + String.valueOf(lpccon[(i - 1) * 4 + 2] + xoffset) + " " + String.valueOf(lpccon[(i - 1) * 4 + 3] + yoffset) + " " + String.valueOf(lpco[i * 2] + xoffset) + " " + String.valueOf(lpco[i * 2 + 1] + yoffset)); else d.append(" L" + String.valueOf(lpco[i * 2] + xoffset) + " " + String.valueOf(lpco[i * 2 + 1] + yoffset)); } return d.toString(); } } tunnelx-20140102.orig/src/Matrix3D.java0000644000000000000000000001232611762432750014367 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; // // // Matrix3D // // class Matrix3D { public float xx = 1.0F, xy = 0.0F, xz = 0.0F, xo = 0.0F; public float yx = 0.0F, yy = 1.0F, yz = 0.0F, yo = 0.0F; public float zx = 0.0F, zy = 0.0F, zz = 1.0F, zo = 0.0F; ///////////////////////////////////////////// public void SetFrom(Matrix3D mat) { xx = mat.xx; xy = mat.xy; xz = mat.xz; xo = mat.xo; yx = mat.yx; yy = mat.yy; yz = mat.yz; yo = mat.yo; zx = mat.zx; zy = mat.zy; zz = mat.zz; zo = mat.zo; } ///////////////////////////////////////////// public void scale(float xf, float yf, float zf) { xx *= xf; xy *= xf; xz *= xf; xo *= xf; yx *= yf; yy *= yf; yz *= yf; yo *= yf; zx *= zf; zy *= zf; zz *= zf; zo *= zf; } ///////////////////////////////////////////// public void translate(float x, float y, float z) { xo += x; yo += y; zo += z; } ///////////////////////////////////////////// public void yrot(double theta) { double ct = Math.cos(theta); double st = Math.sin(theta); float Nxx = (float) (xx * ct + zx * st); float Nxy = (float) (xy * ct + zy * st); float Nxz = (float) (xz * ct + zz * st); float Nxo = (float) (xo * ct + zo * st); float Nzx = (float) (zx * ct - xx * st); float Nzy = (float) (zy * ct - xy * st); float Nzz = (float) (zz * ct - xz * st); float Nzo = (float) (zo * ct - xo * st); xx = Nxx; xy = Nxy; xz = Nxz; xo = Nxo; zx = Nzx; zy = Nzy; zz = Nzz; zo = Nzo; } ///////////////////////////////////////////// public void xrotdeg(double theta) { double ct = TN.degcos(theta); double st = TN.degsin(theta); float Nyx = (float) (yx * ct + zx * st); float Nyy = (float) (yy * ct + zy * st); float Nyz = (float) (yz * ct + zz * st); float Nyo = (float) (yo * ct + zo * st); float Nzx = (float) (zx * ct - yx * st); float Nzy = (float) (zy * ct - yy * st); float Nzz = (float) (zz * ct - yz * st); float Nzo = (float) (zo * ct - yo * st); yx = Nyx; yy = Nyy; yz = Nyz; yo = Nyo; zx = Nzx; zy = Nzy; zz = Nzz; zo = Nzo; } ///////////////////////////////////////////// public void zrotdeg(double theta) { double ct = TN.degcos(theta); double st = TN.degsin(theta); float Nyx = (float) (yx * ct + xx * st); float Nyy = (float) (yy * ct + xy * st); float Nyz = (float) (yz * ct + xz * st); float Nyo = (float) (yo * ct + xo * st); float Nxx = (float) (xx * ct - yx * st); float Nxy = (float) (xy * ct - yy * st); float Nxz = (float) (xz * ct - yz * st); float Nxo = (float) (xo * ct - yo * st); yx = Nyx; yy = Nyy; yz = Nyz; yo = Nyo; xx = Nxx; xy = Nxy; xz = Nxz; xo = Nxo; } void mult(Matrix3D rhs) { float lxx = xx * rhs.xx + yx * rhs.xy + zx * rhs.xz; float lxy = xy * rhs.xx + yy * rhs.xy + zy * rhs.xz; float lxz = xz * rhs.xx + yz * rhs.xy + zz * rhs.xz; float lxo = xo * rhs.xx + yo * rhs.xy + zo * rhs.xz + rhs.xo; float lyx = xx * rhs.yx + yx * rhs.yy + zx * rhs.yz; float lyy = xy * rhs.yx + yy * rhs.yy + zy * rhs.yz; float lyz = xz * rhs.yx + yz * rhs.yy + zz * rhs.yz; float lyo = xo * rhs.yx + yo * rhs.yy + zo * rhs.yz + rhs.yo; float lzx = xx * rhs.zx + yx * rhs.zy + zx * rhs.zz; float lzy = xy * rhs.zx + yy * rhs.zy + zy * rhs.zz; float lzz = xz * rhs.zx + yz * rhs.zy + zz * rhs.zz; float lzo = xo * rhs.zx + yo * rhs.zy + zo * rhs.zz + rhs.zo; xx = lxx; xy = lxy; xz = lxz; xo = lxo; yx = lyx; yy = lyy; yz = lyz; yo = lyo; zx = lzx; zy = lzy; zz = lzz; zo = lzo; } ///////////////////////////////////////////// public void unit() { xx = 1.0F; xy = 0.0F; xz = 0.0F; xo = 0.0F; yx = 0.0F; yy = 1.0F; yz = 0.0F; yo = 0.0F; zx = 0.0F; zy = 0.0F; zz = 1.0F; zo = 0.0F; } ///////////////////////////////////////////// public void SetQuat(float qx, float qy, float qz, float qw) { float norm = qx * qx + qy * qy + qz * qz + qw * qw; float fac = 2.0F / (norm != 0.0F ? norm : 1.0F); xx = 1.0F - (qy * qy + qz * qz) * fac; xy = (qx * qy - qw * qz) * fac; xz = (qx * qz + qw * qy) * fac; yx = (qx * qy + qw * qz) * fac; yy = 1.0F - (qx * qx + qz * qz) * fac; yz = (qy * qz - qw * qx) * fac; zx = (qx * qz - qw * qy) * fac; zy = (qy * qz + qw * qx) * fac; zz = 1.0F - (qx * qx + qy * qy) * fac; xo = 0.0F; yo = 0.0F; zo = 0.0F; } } tunnelx-20140102.orig/src/SubsetAttr.java0000644000000000000000000002313611762432750015035 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2007 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.BasicStroke; import java.awt.Font; import java.awt.Color; import java.util.Map; import java.util.HashMap; import java.util.SortedMap; import java.util.TreeMap; import java.util.List; import java.util.ArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; ///////////////////////////////////////////// class SubsetAttr { // This is used to run variables available in all the parameters // so we can change the settings of the colours or all the linestyles and fonts at // once, if they refer to a variable rather than an absolute setting. // May in future handle expressions. Map vvarsettings = new HashMap(); // variable->value static Color coldefalt = new Color(0); String subsetname = null; String uppersubset = null; SubsetAttr uppersubsetattr = null; SortedMap subsetsdownmap = new TreeMap(); boolean bViewhidden = false; // tsvpathsviz - would mean it doesn't get into tsvpathsviz String sareamaskcolour = null; String sareacolour = null; Color areamaskcolour = null; Color areacolour = null; LineStyleAttr[] linestyleattrs = new LineStyleAttr[LineStyleAttr.Nlinestyles]; LineStyleAttr[] shadowlinestyleattrs = new LineStyleAttr[LineStyleAttr.Nlinestyles]; Map labelfontsmap = new HashMap(); Map subautsymbolsmap = new HashMap(); ///////////////////////////////////////////// SubsetAttr(String lsubsetname) { subsetname = lsubsetname; } ///////////////////////////////////////////// static List alreadyusedeval = new ArrayList(); String EvalVars(String str) { alreadyusedeval.clear(); if (str == null) return str; while (str.indexOf('$') != -1) { //String Dstr = str; int naue = alreadyusedeval.size(); Matcher mdvar = Pattern.compile("(\\$\\w+);?").matcher(str); while (mdvar.find()) { if (!alreadyusedeval.contains(mdvar.group(1)) && vvarsettings.containsKey(mdvar.group(1))) alreadyusedeval.add(mdvar.group(1)); } if (naue == alreadyusedeval.size()) break; while (naue < alreadyusedeval.size()) { // escape the leading $ str = str.replaceAll("\\" + alreadyusedeval.get(naue) + ";?", vvarsettings.get(alreadyusedeval.get(naue))); naue++; } //System.out.println("Variable substitution: " + Dstr + " => " + str); } // substitute if (uppersubsetattr != null) return uppersubsetattr.EvalVars(str); // need to evaluate equations here, eg "1.5 * 7" str = str.trim(); //System.out.println(str + " from- " + toString()); //assert str.matches("#[0-9A-Fa-f]{8}|[\\d\\.\\-]*$"); return str; } ///////////////////////////////////////////// static Color ConvertColour(String coldef, Color defalt) { if (coldef == null) return defalt; if (coldef.equalsIgnoreCase("none")) return null; if (!coldef.startsWith("#")) TN.emitError("Colour value should be hex starting with #: " + coldef); int col = 0; try { col = (int)Long.parseLong(coldef.substring(1), 16); } catch (NumberFormatException nfe) { TN.emitError("Hex number format exception: "+coldef.substring(1)); } return new Color(col, ((col & 0xff000000) != 0)); } ///////////////////////////////////////////// // this will in future be string tokenizing on * / ( and ) to evaluate equations static float ConvertFloat(String fdef, float defalt) { if (fdef == null) return defalt; fdef = fdef.trim(); assert fdef.matches("[\\d\\.\\-]+$"); return Float.parseFloat(fdef); } ///////////////////////////////////////////// // just for consistency static String ConvertString(String sdef, String defalt) { if (sdef == null) return defalt; return sdef.trim(); } ///////////////////////////////////////////// // used for copying over SubsetAttrStyles SubsetAttr(SubsetAttr lsa) { subsetname = lsa.subsetname; uppersubset = lsa.uppersubset; sareamaskcolour = lsa.sareamaskcolour; sareacolour = lsa.sareacolour; areamaskcolour = lsa.areamaskcolour; areacolour = lsa.areacolour; // copy defined fonts for (LabelFontAttr lfa : lsa.labelfontsmap.values()) labelfontsmap.put(lfa.labelfontname, new LabelFontAttr(lfa, this)); // copy over defined linestyles things for (int i = 0; i < LineStyleAttr.Nlinestyles; i++) { linestyleattrs[i] = (lsa.linestyleattrs[i] != null ? new LineStyleAttr(lsa.linestyleattrs[i]) : null); shadowlinestyleattrs[i] = (lsa.shadowlinestyleattrs[i] != null ? new LineStyleAttr(lsa.shadowlinestyleattrs[i]) : null); } // list of symbols. for (SymbolStyleAttr ssa : lsa.subautsymbolsmap.values()) subautsymbolsmap.put(ssa.symbolname, new SymbolStyleAttr(ssa)); // list of variables. vvarsettings.putAll(lsa.vvarsettings); } ///////////////////////////////////////////// void SetVariable(String svar, String sval) { if (!svar.matches("\\$\\w+$")) TN.emitError("variables must begin with $ and only contain letters and numbers:" + svar + " -> " + sval); if (sval.matches(".*\\" + svar + "\\W")) TN.emitError("variables must not contain self-references:" + svar + " -> " + sval); if (sval.equals(TNXML.sATTR_VARIABLE_VALUE_CLEAR)) vvarsettings.remove(svar); else vvarsettings.put(svar, sval); } ///////////////////////////////////////////// void SetLinestyleAttr(int llinestyle, String lsstrokewidth, String lsspikegap, String lsgapleng, String lsspikeheight, String lsstrokecolour, String lsshadowstrokewidth, String lsshadowstrokecolour) { if ((llinestyle == SketchLineStyle.SLS_INVISIBLE) || (llinestyle == SketchLineStyle.SLS_CONNECTIVE)) TN.emitWarning("only renderable linestyles please"); linestyleattrs[llinestyle] = new LineStyleAttr(llinestyle, lsstrokewidth, lsspikegap, lsgapleng, lsspikeheight, lsstrokecolour); shadowlinestyleattrs[llinestyle] = new LineStyleAttr(llinestyle, lsshadowstrokewidth, "0", "0", "0", lsshadowstrokecolour); } ///////////////////////////////////////////// static Color defaltareamaskcolour = new Color(1.0F, 1.0F, 1.0F, 0.55F); static Color defaltareacolour = new Color(0.8F, 0.9F, 0.9F, 0.4F); void FillMissingAttribs() // this function is called recursing down the tree in order { //System.out.println("FillMissingAttribsFillMissingAttribs " + subsetname); // pull unset defaults down from the upper case if ((sareamaskcolour == null) && (uppersubsetattr != null)) sareamaskcolour = uppersubsetattr.sareamaskcolour; if ((sareacolour == null) && (uppersubsetattr != null)) sareacolour = uppersubsetattr.sareacolour; areamaskcolour = SubsetAttr.ConvertColour(EvalVars(sareamaskcolour), defaltareamaskcolour); areacolour = SubsetAttr.ConvertColour(EvalVars(sareacolour), defaltareacolour); if (uppersubsetattr != null) { for (LabelFontAttr llfa : uppersubsetattr.labelfontsmap.values()) { if (!labelfontsmap.containsKey(llfa.labelfontname)) labelfontsmap.put(llfa.labelfontname, new LabelFontAttr(llfa, this)); } } // fill in the missing font attributes in each case for (LabelFontAttr lfa : labelfontsmap.values()) lfa.FillMissingAttribsLFA(uppersubsetattr != null ? uppersubsetattr.labelfontsmap.get(lfa.labelfontname) : null); // fill in the missing symbol attributes for (SymbolStyleAttr ssa : subautsymbolsmap.values()) ssa.FillMissingAttribsSSA(uppersubsetattr != null ? uppersubsetattr.subautsymbolsmap.get(ssa.symbolname) : null); // copy in any symbols that aren't there already if (uppersubsetattr != null) { for (SymbolStyleAttr ussa : uppersubsetattr.subautsymbolsmap.values()) { if (!subautsymbolsmap.containsKey(ussa.symbolname)) subautsymbolsmap.put(ussa.symbolname, ussa); } for (LabelFontAttr ulfa : uppersubsetattr.labelfontsmap.values()) { if (!labelfontsmap.containsKey(ulfa.labelfontname)) labelfontsmap.put(ulfa.labelfontname, ulfa); } } // copy over defined linestyles things and fill in gaps for (int i = 0; i < LineStyleAttr.Nlinestyles; i++) { if ((i == SketchLineStyle.SLS_INVISIBLE) || (i == SketchLineStyle.SLS_CONNECTIVE)) continue; if (linestyleattrs[i] == null) linestyleattrs[i] = (uppersubsetattr != null ? new LineStyleAttr(uppersubsetattr.linestyleattrs[i]) : new LineStyleAttr(i)); if (shadowlinestyleattrs[i] == null) shadowlinestyleattrs[i] = (uppersubsetattr != null ? new LineStyleAttr(uppersubsetattr.shadowlinestyleattrs[i]) : new LineStyleAttr(i)); linestyleattrs[i].Construct(this, Color.black); shadowlinestyleattrs[i].Construct(this, null); } } ///////////////////////////////////////////// public String toString() { return (bViewhidden ? ("[X] " + subsetname) : subsetname); } }; tunnelx-20140102.orig/src/stripcntlm.py0000644000000000000000000000020111762432750014627 0ustar import re, sys a = open(sys.argv[1]) b = a.read(); a.close() a = open(sys.argv[1], "w") a.write(re.sub("\r", "", b)) a.close() tunnelx-20140102.orig/src/Graphics2Dadapter.java0000644000000000000000000002235311762432750016224 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Font; import java.awt.Color; import java.awt.Polygon; import java.awt.BasicStroke; import java.awt.Shape; import java.awt.FontMetrics; import java.awt.geom.AffineTransform; import java.text.AttributedCharacterIterator; import java.awt.geom.AffineTransform; import java.awt.font.GlyphVector; import java.awt.image.BufferedImage; import java.awt.image.BufferedImageOp; import java.awt.image.RenderedImage; import java.awt.image.renderable.RenderableImage; import java.awt.RenderingHints; import java.awt.image.ImageObserver; import java.awt.image.renderable.RenderableImageOp; import java.awt.Image; import java.awt.Stroke; import java.awt.Composite; import java.awt.Rectangle; import java.awt.Paint; import java.awt.GraphicsConfiguration; import java.awt.font.FontRenderContext; import java.util.Map; ///////////////////////////////////////////// public class Graphics2Dadapter extends Graphics2D { private boolean bnotimplemented() { assert false; return false; } private Object notimplemented() { assert false; return null; } public Graphics2Dadapter() { this("Untitled"); } public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { notimplemented(); } public Graphics2Dadapter(String title) { } public void draw3DRect(int x, int y, int width, int height, boolean raised) { notimplemented(); } public void fill3DRect(int x, int y, int width, int height, boolean raised) { notimplemented(); } public void draw(Shape s) { notimplemented(); } public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) { return bnotimplemented(); } public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) { notimplemented(); } public void drawRenderedImage(RenderedImage img, AffineTransform xform) { notimplemented(); } public void drawRenderableImage(RenderableImage img, AffineTransform xform) { notimplemented(); } public void drawString(String str, int x, int y) { notimplemented(); } public void drawString(String s, float x, float y) { notimplemented(); } public void drawString(AttributedCharacterIterator iterator, int x, int y) { notimplemented(); } public void drawString(AttributedCharacterIterator iterator, float x, float y) { notimplemented(); } public void drawGlyphVector(GlyphVector g, float x, float y) { notimplemented(); } public void fill(Shape s) { notimplemented(); } public boolean hit(Rectangle rect, Shape s, boolean onStroke) { return bnotimplemented(); } public GraphicsConfiguration getDeviceConfiguration() { return (GraphicsConfiguration)notimplemented(); } public void setComposite(Composite comp) { notimplemented(); } public void setPaint(Paint paint) { notimplemented(); } public void setStroke(Stroke s) { notimplemented(); } public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue) { notimplemented(); } public Object getRenderingHint(RenderingHints.Key hintKey) { return notimplemented(); } // Uncomment the stuff for Java 1.5 public void addRenderingHints(Map/**/ hints) { notimplemented(); } public void setRenderingHints(Map/**/ hints) { notimplemented(); } public RenderingHints getRenderingHints() { return (RenderingHints)notimplemented(); } public void translate(int x, int y) { notimplemented(); } public void translate(double tx, double ty) { notimplemented(); } public void rotate(double theta) { notimplemented(); } public void rotate(double theta, double x, double y) { notimplemented(); } public void scale(double sx, double sy) { notimplemented(); } public void shear(double shx, double shy) { notimplemented(); } public void transform(AffineTransform Tx) { notimplemented(); } public void setTransform(AffineTransform Tx) { notimplemented(); } public AffineTransform getTransform() { return (AffineTransform)notimplemented(); } public Paint getPaint() { return (Paint)notimplemented(); } public Composite getComposite() { return (Composite)notimplemented(); } public void setBackground(Color color) { notimplemented(); } public Color getBackground() { return (Color)notimplemented(); } public Stroke getStroke() { return (Stroke)notimplemented(); } public void clip(Shape s) { notimplemented(); } public FontRenderContext getFontRenderContext() { return (FontRenderContext)notimplemented(); } public Graphics create() { return (Graphics)notimplemented(); } public Graphics create(int x, int y, int width, int height) { return (Graphics)notimplemented(); } public Color getColor() { return (Color)notimplemented(); } public void setColor(Color c) { notimplemented(); } public void setPaintMode() { notimplemented(); } public void setXORMode(Color c1) { notimplemented(); } public Font getFont() { return (Font)notimplemented(); } public void setFont(Font font) { notimplemented(); } public FontMetrics getFontMetrics() { return (FontMetrics)notimplemented(); } public FontMetrics getFontMetrics(Font f) { return (FontMetrics)notimplemented(); } public Rectangle getClipBounds() { return (Rectangle)notimplemented(); } public void clipRect(int x, int y, int width, int height) { notimplemented(); } public void setClip(int x, int y, int width, int height) { notimplemented(); } public Shape getClip() { return (Shape)notimplemented(); } public void setClip(Shape clip) { notimplemented(); } public void copyArea(int x, int y, int width, int height, int dx, int dy) { notimplemented(); } public void drawLine(int x1, int y1, int x2, int y2) { notimplemented(); } public void fillRect(int x, int y, int width, int height) { notimplemented(); } public void drawRect(int x, int y, int width, int height) { notimplemented(); } public void clearRect(int x, int y, int width, int height) { notimplemented(); } public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { notimplemented(); } public void drawOval(int x, int y, int width, int height) { notimplemented(); } public void fillOval(int x, int y, int width, int height) { notimplemented(); } public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) { notimplemented(); } public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) { notimplemented(); } public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints) { notimplemented(); } public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) { notimplemented(); } public void drawPolygon(Polygon p) { notimplemented(); } public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints) { notimplemented(); } public void fillPolygon(Polygon p) { notimplemented(); } public void drawChars(char[] data, int offset, int length, int x, int y) { notimplemented(); } public void drawBytes(byte[] data, int offset, int length, int x, int y) { notimplemented(); } public boolean drawImage(Image img, int x, int y, ImageObserver observer) { return bnotimplemented(); } public boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) { return bnotimplemented(); } public boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer) { return bnotimplemented(); } public boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer) { return bnotimplemented(); } public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer) { return bnotimplemented(); } public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer) { return bnotimplemented(); } public void dispose() { notimplemented(); } public void finalize() { super.finalize(); } public String toString() { return (String)notimplemented(); } public boolean hitClip(int x, int y, int width, int height) { return bnotimplemented(); } public Rectangle getClipBounds(Rectangle r) { return (Rectangle)notimplemented(); } } tunnelx-20140102.orig/src/MainBox.java0000644000000000000000000006203512261213471014263 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.io.IOException; import java.io.InputStreamReader; import java.io.BufferedReader; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.Dimension; import java.awt.Point; import java.awt.Color; import javax.swing.JFrame; import javax.swing.JSplitPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.JScrollPane; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JMenuBar; import javax.swing.JCheckBoxMenuItem; import javax.swing.JOptionPane; import javax.swing.JApplet; import java.lang.ClassLoader; import java.util.List; import java.util.ArrayList; import javax.swing.text.BadLocationException; // The tilt coding stuff // Be able to switch between two sketches in the same SketchDisplay (the background one) // Be able to save more than one sketch in the same file (the imported ones // to do: // see ElevWarp.java for more todos // save to url makes it green // do whole list of tunnel files available at same time // sort out backgrounds // the survex file open to do its own removing of http: crud from the front // bring in background images through this // open with http on command line should work // new sketch is made relative to the disk?? // the tree in the tunnel file list can be used to import images // and it should refresh // and it should open sketches directly from it. // then we can lose the list view. // save as from http file should work // upload and upload as... should post up to directory // upload rendered image should do something in troggle (some kind of workspace) // upload background images for sure // cached background images that have been pulled down // when the browser thing is working, we can emulate it in tunnel (mainbox?) // fix lookup for symbols location // comments in symbols directory // reloadfontcolours ///////////////////////////////////////////// ///////////////////////////////////////////// // the main frame public class MainBox extends JFrame // extends JApplet // AppletConversion { // the parameters used in this main box // the survey tree TunnelFileList tunnelfilelist; TunnelLoader tunnelloader; JCheckBoxMenuItem miViewSymbolsList; JCheckBoxMenuItem miNetConnection; JTextArea textareaerrors = new JTextArea("Errors and warnings here\n========================\n"); List allfontcolours = new ArrayList(); // this could be moved into TunnelFileList List ftsketches = new ArrayList(); // this could be a map List vgsymbolstsketches = new ArrayList(); InstantHelp instanthelp = null; // the default treeroot with list of symbols. FileAbstraction vgsymbolsdirectory; // single xsection window and wireframe display WireframeDisplay wireframedisplay = new WireframeDisplay(); // sketch display window SketchDisplay sketchdisplay; // for handling multi-threaded layouts of symbols static SymbolLayoutProcess symbollayoutprocess; NetConnection netconnection = new NetConnection(this); ///////////////////////////////////////////// void MainRefresh() { tunnelfilelist.RemakeTFList(); } ///////////////////////////////////////////// void MainOpen(FileAbstraction fileauto, int ftype) { if (fileauto != null) TN.emitMessage("Auto load: " + fileauto + " of type: " + ftype); //if (bAuto) // TN.emitMessage("Auto load: " + TN.currentDirectory + " of type: " + ftype); // Everything is svxfile SvxFileDialog sfiledialog = (fileauto == null ? SvxFileDialog.showOpenDialog(TN.currentDirectory, this, ftype, false) : SvxFileDialog.showOpenDialog(fileauto, this, ftype, true)); if ((sfiledialog == null) || ((sfiledialog.svxfile == null) && (sfiledialog.tunneldirectory == null))) return; String soname = (sfiledialog.tunneldirectory == null ? sfiledialog.svxfile.getName() : sfiledialog.tunneldirectory.getName()); int il = soname.indexOf('.'); if (il != -1) soname = soname.substring(0, il); // put the tunnel in String filetunnname = soname.replace(' ', '_').replace('\t', '_'); // can't cope with spaces. // loading directly from a tunnel directory tree if (sfiledialog.tunneldirectory != null) { try { if ((sfiledialog.tunneldirectory.localfile != null) && sfiledialog.tunneldirectory.isDirectory()) TN.currentDirectory = sfiledialog.tunneldirectory; tunnelfilelist.AddTreeDirectory(sfiledialog.tunneldirectory); int nfl = allfontcolours.size(); sfiledialog.tunneldirectory.FindFilesOfDirectory(ftsketches, allfontcolours); tunnelfilelist.RemakeTFList(); // do it here so the list entries get sorted out quickly before they get caught out // this whole preview function needs dealing with; poss to remove the situation that it handles multiple lists for (int i = nfl; i < allfontcolours.size(); i++) tunnelloader.LoadFontcolour(allfontcolours.get(i)); } catch (IOException ie) { TN.emitWarning(ie.toString()); ie.printStackTrace(); } catch (NullPointerException e) { TN.emitWarning(e.toString()); e.printStackTrace(); }; // update any symbols information that may have showed up in the process if (sketchdisplay.sketchlinestyle.bsubsetattributesneedupdating) sketchdisplay.sketchlinestyle.UpdateSymbols(false); } // loading a survex file else if (sfiledialog.svxfile.xfiletype == FileAbstraction.FA_FILE_SVX) { if (sfiledialog.svxfile.localfile != null) TN.currentDirectory = sfiledialog.svxfile.getParentFile(); TN.emitMessage("Do the SVX loading: " + ftype); NewSketch(sfiledialog.svxfile, sfiledialog.svxfile.getSketchName() + "-sketch", (sketchdisplay.subsetpanel.jcbsubsetstyles.getItemCount() != 0 ? 0 : -1)); TN.emitMessage("import centerline: "); if (sketchdisplay.ImportSketchCentrelineFile(sfiledialog)) { TN.emitMessage("import survex centrline: "); sketchdisplay.ImportCentrelineLabel("normal"); sketchdisplay.sketchgraphicspanel.MaxAction(2); TN.emitMessage("Done"); } } // (unintentionally different from the xfiletype thing above) It doesn't know if the XML actually contains a sketch else if (ftype == SvxFileDialog.FT_XMLSKETCH) { sfiledialog.svxfile.xfiletype = sfiledialog.svxfile.GetFileType(); // part of the constructor? if (sfiledialog.svxfile.localfile != null) TN.currentDirectory = sfiledialog.svxfile.getParentFile(); if ((sfiledialog.svxfile.xfiletype == FileAbstraction.FA_FILE_XML_SKETCH)) { OneSketch tsketch = new OneSketch(sfiledialog.svxfile); if (GetActiveTunnelSketches() == vgsymbolstsketches) { tsketch.sketchsymbolname = tsketch.sketchfile.getName(); tsketch.bSymbolType = true; } GetActiveTunnelSketches().add(tsketch); tunnelfilelist.RemakeTFList(); tunnelfilelist.tflist.setSelectedIndex(tunnelfilelist.isketche - 1); tunnelfilelist.UpdateSelect(true); // doubleclicks it. TN.emitMessage(" -EEE- " + GetActiveTunnelSketches().size()); } else TN.emitError("Skipping file of unrecognized type "+sfiledialog.svxfile.xfiletype); } // loading a survex file else if ((sfiledialog.svxfile.xfiletype == FileAbstraction.FA_FILE_POCKET_TOPO) || (sfiledialog.svxfile.xfiletype == FileAbstraction.FA_FILE_POCKET_BINTOP)) { if (sfiledialog.svxfile.localfile != null) TN.currentDirectory = sfiledialog.svxfile.getParentFile(); TN.emitMessage("Do the POCKETTOPO loading: " + ftype); NewSketch(sfiledialog.svxfile, sfiledialog.svxfile.getSketchName() + "-sketch", (sketchdisplay.subsetpanel.jcbsubsetstyles.getItemCount() != 0 ? 0 : -1)); TN.emitMessage("import centreline: "); if (sketchdisplay.ImportSketchCentrelineFile(sfiledialog)) { TN.emitMessage("worked: Now importing actual centreline"); // this could be a menu option? sketchdisplay.ImportCentrelineLabel("nosurvex"); sketchdisplay.ImportCentrelineLabel("TOPelevation"); sketchdisplay.subsetpanel.SetSubsetStyleFromString("pockettopo"); sketchdisplay.sketchgraphicspanel.MaxAction(2); } } else TN.emitError("can't do this type any more no more: " + ftype); //MainRefresh(); } ///////////////////////////////////////////// void MainSaveAll() { for (OneSketch lsketch : ftsketches) lsketch.SaveSketch(); for (OneSketch lsketch : vgsymbolstsketches) lsketch.SaveSketch(); tunnelfilelist.tflist.repaint(); } ///////////////////////////////////////////// void MainExit() { if (JOptionPane.showConfirmDialog(this, "Are you sure you want to quit?", "Quit?", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) System.exit(0); } ///////////////////////////////////////////// public void emitErrorMessageLine(String mess, boolean btofront) { textareaerrors.append(mess); if (btofront) toFront(); int lc = textareaerrors.getLineCount() - 1; try { textareaerrors.setSelectionStart(textareaerrors.getLineStartOffset(lc)); textareaerrors.setSelectionEnd(textareaerrors.getLineEndOffset(lc)); } catch (BadLocationException e) {;} } ///////////////////////////////////////////// ///////////////////////////////////////////// // build a sketch window. void ViewSketch(OneSketch activesketch) { if (activesketch != null) { boolean bloaded = true; ; if (!activesketch.bsketchfileloaded) bloaded = tunnelloader.LoadSketchFile(activesketch, true); if (bloaded) sketchdisplay.ActivateSketchDisplay(activesketch, true); } tunnelfilelist.tflist.repaint(); } ///////////////////////////////////////////// // make a new sketch void NewSketch(FileAbstraction fanewsketchdir, String lname, int subsetstyleindex) { // if new symbols type we should be able to edit the name before creating. // determin if this is the sketch type (needs refining) OneSketch tsketch = new OneSketch(FileAbstraction.GetUniqueSketchFileName(fanewsketchdir, GetActiveTunnelSketches(), lname)); if (GetActiveTunnelSketches() == vgsymbolstsketches) { tsketch.sketchsymbolname = tsketch.sketchfile.getName(); tsketch.bSymbolType = true; } tsketch.SetupSK(); // default to first value if (subsetstyleindex != -1) tsketch.SetSubsetAttrStyle(((SubsetAttrStyle)sketchdisplay.subsetpanel.jcbsubsetstyles.getItemAt(subsetstyleindex)), null); tsketch.bsketchfilechanged = true; // load into the structure and view it. assert tsketch.bsketchfileloaded; GetActiveTunnelSketches().add(tsketch); tunnelfilelist.RemakeTFList(); tunnelfilelist.tflist.setSelectedIndex(tunnelfilelist.isketche - 1); tunnelfilelist.UpdateSelect(true); // doubleclicks it. } ///////////////////////////////////////////// OneSketch FindSketchFrame(List tsketches, FileAbstraction fasketch) { System.out.println("finding sketchframes " + tsketches.size() + " " + fasketch.getPath()); // account for which sketches have actually been loaded for (OneSketch ltsketch : tsketches) { if (fasketch.equals(ltsketch.sketchfile)) { if (ltsketch.bsketchfileloaded) return ltsketch; else { tunnelloader.LoadSketchFile(ltsketch, true); tunnelfilelist.tflist.repaint(); return ltsketch; } } } fasketch.xfiletype = fasketch.GetFileType(); // part of the constructor? OneSketch tsketch = new OneSketch(fasketch); if (GetActiveTunnelSketches() == vgsymbolstsketches) { tsketch.sketchsymbolname = tsketch.sketchfile.getName(); tsketch.bSymbolType = true; } tunnelloader.LoadSketchFile(tsketch, true); // if fails return null GetActiveTunnelSketches().add(tsketch); tunnelfilelist.tflist.repaint(); tunnelfilelist.RemakeTFList(); return tsketch; } ///////////////////////////////////////////// void UpdateSketchFrames(OneSketch tsketch, int iProper) { List framesketchesseen = (iProper != SketchGraphics.SC_UPDATE_NONE ? new ArrayList() : null); for (OneSArea osa : tsketch.vsareas) { if ((osa.iareapressig == SketchLineStyle.ASE_SKETCHFRAME) && (osa.opsketchframedefs != null)) { for (OnePath op : osa.opsketchframedefs) { SketchFrameDef sketchframedef = op.plabedl.sketchframedef; if (!op.bpathvisiblesubset) { System.out.println("skipping outofsubset sketchframe"); continue; } sketchframedef.SetSketchFrameFiller(this, tsketch.realposterpaperscale, tsketch.sketchLocOffset, tsketch.sketchfile); OneSketch lpframesketch = sketchframedef.pframesketch; if ((iProper != SketchGraphics.SC_UPDATE_NONE) && (lpframesketch != null)) { // got to consider setting the sket SubsetAttrStyle sksas = sketchdisplay.sketchlinestyle.subsetattrstylesmap.get(sketchframedef.sfstyle); if ((sksas == null) && (sketchframedef.pframesketch.sksascurrent == null)) sksas = sketchdisplay.subsetpanel.sascurrent; if ((sksas != null) && (sksas != sketchframedef.pframesketch.sksascurrent) && !framesketchesseen.contains(lpframesketch)) { TN.emitMessage("Setting sketchstyle to " + sksas.stylename + " (maybe should relay the symbols)"); int scchangetyp = sketchframedef.pframesketch.SetSubsetAttrStyle(sksas, sketchdisplay.sketchlinestyle.pthstyleareasigtab.sketchframedefCopied); SketchGraphics.SketchChangedStatic(scchangetyp, lpframesketch, null); } // SketchGraphics.SC_UPDATE_ALL_BUT_SYMBOLS or SketchGraphics.SC_UPDATE_ALL lpframesketch.UpdateSomething(iProper, false); SketchGraphics.SketchChangedStatic(iProper, lpframesketch, null); } if ((framesketchesseen != null) && !framesketchesseen.contains(lpframesketch)) framesketchesseen.add(lpframesketch); } } } } ///////////////////////////////////////////// ///////////////////////////////////////////// ///////////////////////////////////////////// public MainBox() // the main construction is done in init() { TN.mainbox = this; textareaerrors.setBackground(new Color(1.0F, 0.8F, 0.8F)); textareaerrors.setRows(4); // hide for AppletConversion setTitle("TunnelX - " + TN.tunnelversion); setLocation(new Point(100, 100)); setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent event) { MainExit(); } } ); } // need to load the fontcolours.xml which will then call in a bunch of symbols that need to be loaded // into vgsymbolss. // each of these resources comes in as a name // // LoadSymbols public void init() { FileAbstraction.InitFA(); if (FileAbstraction.helpFile != null) instanthelp = new InstantHelp(this); sketchdisplay = new SketchDisplay(this); tunnelloader = new TunnelLoader(false, sketchdisplay.sketchlinestyle); tunnelfilelist = new TunnelFileList(this); symbollayoutprocess = new SymbolLayoutProcess(this); JMenuItem miOpenXMLDir = new JMenuItem("Open Sketches Directory..."); miOpenXMLDir.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { MainOpen(null, SvxFileDialog.FT_DIRECTORY); } } ); JMenuItem miOpen = new JMenuItem("Open Sketch..."); miOpen.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { MainOpen(null, SvxFileDialog.FT_XMLSKETCH); } } ); JMenuItem miOpenSVX = new JMenuItem("Open Survex..."); miOpenSVX.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { MainOpen(null, SvxFileDialog.FT_SVX); } } ); JMenuItem miSaveAll = new JMenuItem("Save All"); miSaveAll.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { MainSaveAll(); } } ); JMenuItem miRefresh = new JMenuItem("Refreshhh"); miRefresh.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { MainRefresh(); } } ); miNetConnection = new JCheckBoxMenuItem("Net Connection", false); miNetConnection.setEnabled(false); JMenuItem miExit = new JMenuItem("Exit"); miExit.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { MainExit(); } } ); JMenuItem miSketch = new JMenuItem("View Sketch"); miSketch.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { ViewSketch((tunnelfilelist.activesketchindex != -1 ? GetActiveTunnelSketches().get(tunnelfilelist.activesketchindex) : null)); } } ); miViewSymbolsList = new JCheckBoxMenuItem("Symbols List", false); miViewSymbolsList.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { tunnelfilelist.RemakeTFList(); } } ); JMenuItem miNewEmptySketch = new JMenuItem("New Empty Sketch"); miNewEmptySketch.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { NewSketch(TN.currentDirectory, "sketch", -1); } } ); // build the layout of the menu bar JMenuBar menubar = new JMenuBar(); JMenu menufile = new JMenu("File"); if (!FileAbstraction.bIsApplet) // or use disable function on them to grey them out. { menufile.add(miOpen); menufile.add(miOpenSVX); menufile.add(miOpenXMLDir); } menufile.add(miNewEmptySketch); menufile.add(miRefresh); if (!FileAbstraction.bIsApplet) { menufile.add(miSaveAll); menufile.add(miNetConnection); menufile.add(miExit); } menubar.add(menufile); JMenu menutunnel = new JMenu("Tunnel"); menutunnel.add(miViewSymbolsList); menutunnel.add(miSketch); menubar.add(menutunnel); if (instanthelp != null) { JMenu menuHelp = new JMenu("Help"); for (JMenuItem mihelp : instanthelp.mihelpsmain) menuHelp.add(mihelp); menubar.add(menuHelp); } setJMenuBar(menubar); tunnelfilelist.setPreferredSize(new Dimension(600, 300)); JSplitPane vsplitpane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); vsplitpane.setLeftComponent(tunnelfilelist); vsplitpane.setRightComponent(new JScrollPane(textareaerrors)); getContentPane().add(vsplitpane); pack(); //hide for AppletConversion tunnelfilelist.jsp.setDividerLocation(0.3); vsplitpane.setDividerLocation(0.8); setVisible(true); // load the symbols from the current working directory. // byproduct is it will load the stoke colours too LoadSymbols(FileAbstraction.currentSymbols); sketchdisplay.miUseSurvex.setSelected(FileAbstraction.SurvexExists()); if (sketchdisplay.sketchlinestyle.bsubsetattributesneedupdating) // false is no subsetattributes ever got loaded (ie wasn't such a file in symbols directory) sketchdisplay.sketchlinestyle.UpdateSymbols(true); if (SketchLineStyle.strokew == -1.0F) { SketchLineStyle.SetStrokeWidths(0.625F, sketchdisplay.miNotDotted.isSelected()); if (sketchdisplay.todenodepanel != null) sketchdisplay.todenodepanel.BuildSpirals(); } } ///////////////////////////////////////////// // we should soon be loading these files from the same place as the svx as well as this general directory void LoadSymbols(FileAbstraction fasymbols) { TN.emitWarning("Loading symbols dir: " + fasymbols.getAbsolutePath()); // do the tunnel loading thing TunnelLoader symbtunnelloader = new TunnelLoader(true, sketchdisplay.sketchlinestyle); try { vgsymbolsdirectory = fasymbols; int nfl = allfontcolours.size(); fasymbols.FindFilesOfDirectory(vgsymbolstsketches, allfontcolours); for (int i = nfl; i < allfontcolours.size(); i++) symbtunnelloader.LoadFontcolour(allfontcolours.get(i)); // load up sketches for (OneSketch tsketch : vgsymbolstsketches) symbtunnelloader.LoadSketchFile(tsketch, false); } catch (IOException ie) { TN.emitWarning(ie.toString()); ie.printStackTrace(); } catch (NullPointerException e) { TN.emitWarning(e.toString()); e.printStackTrace(); }; } ///////////////////////////////////////////// List GetActiveTunnelSketches() { return (miViewSymbolsList.isSelected() ? vgsymbolstsketches : ftsketches); } ///////////////////////////////////////////// // startup the program public static void main(String args[]) { //System.out.println("Content-Type: text/plain\n"); //System.out.println("Hi there"); //System.exit(0); String fstart = null; // produce a default //fstart = "http://seagrass.goatchurch.org.uk/~expo/tunneldata/"; String snetconnection = null; boolean bmakeimages = false; boolean btwotone = false; for (int i = 0; i < args.length; i++) { if (!args[i].substring(0, 2).equals("--")) fstart = args[i]; else if (args[i].equals("--verbose")) TN.bVerbose = true; else if (args[i].equals("--quiet")) TN.bVerbose = false; else if (args[i].equals("--todenode")) TN.bTodeNode = true; else if (args[i].equals("--netconnection")) snetconnection = "http://localhost:8000/run/tunnelx_receiver/"; else if (args[i].equals("--makeimages")) bmakeimages = true; else if (args[i].startsWith("--printdir=")) TN.currprintdir = FileAbstraction.MakeDirectoryFileAbstraction(args[i].substring(11)); else if (args[i].equals("--twotone")) btwotone = true; else TN.emitWarning("Unknown arg: " + args[i]); } // start-up FileAbstraction.bIsApplet = false; TN.currentDirectory = FileAbstraction.MakeCurrentUserDirectory(); TN.currentDirectoryIMG = FileAbstraction.MakeCurrentUserDirectory(); MainBox mainbox = new MainBox(); mainbox.init(); // the init gets called if (btwotone) mainbox.sketchdisplay.printingpanel.cbBitmaptype.setSelectedIndex(2); // do the filename if (fstart != null) { FileAbstraction fastart = FileAbstraction.MakeOpenableFileAbstraction(fstart); fastart = FileAbstraction.MakeCanonical(fastart); if (fastart.localurl == null) TN.currentDirectory = fastart; fastart.xfiletype = fastart.GetFileType(); int ftype = (fastart.isDirectory() ? SvxFileDialog.FT_DIRECTORY : (fastart.xfiletype == FileAbstraction.FA_FILE_XML_SKETCH ? SvxFileDialog.FT_XMLSKETCH : SvxFileDialog.FT_SVX)); mainbox.MainOpen(fastart, ftype); } // the command line to generate bitmaps directly from all the frame sketches if (bmakeimages) { if ((fstart != null) && (mainbox.sketchdisplay.sketchgraphicspanel.tsketch != null)) mainbox.sketchdisplay.MakeImages(); else TN.emitError("Must specify a sketch on the command line to do makeimages"); } if (snetconnection != null) mainbox.netconnection.ncstart(snetconnection); } ///////////////////////////////////////////// boolean bFileLoaded = false; public void start() { assert FileAbstraction.bIsApplet; if (bFileLoaded) return; ClassLoader cl = MainBox.class.getClassLoader(); TN.currentDirectory = new FileAbstraction(); TN.currentDirectoryIMG = new FileAbstraction(); // uncomment for AppletConversion // TN.currentDirectory.localurl = cl.getResource(getParameter("cavedir")); // TN.currentDirectory.bIsDirType = true; // System.out.println("inputdir: " + getParameter("cavedir")); // System.out.println("currentdir: " + TN.currentDirectory.localurl); // MainOpen(true, SvxFileDialog.FT_DIRECTORY); //LoadTunnelDirectoryTree("cavecave", TN.currentDirectory); MainRefresh(); bFileLoaded = true; } ///////////////////////////////////////////// public void stop() { } ///////////////////////////////////////////// public void destroy() { } ///////////////////////////////////////////// public String getAppletInfo() { return "tunnelx applet. Protected by the GPL"; } } tunnelx-20140102.orig/src/ElevWarp.java0000644000000000000000000005334711762432750014471 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2007 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.util.List; import java.util.ArrayList; import java.util.Map; import java.util.HashMap; import java.util.Set; import java.util.HashSet; import java.awt.geom.Point2D; import java.awt.geom.Ellipse2D; import java.awt.geom.GeneralPath; // the tree thing in the left crashes when I click on some of the elements // very often the main file list isn't showing up. (some sort of rendering is too early) // Make A4 should not need frame to be selected. Just put in corner +100x100 // the XC Subset doesn't update the subsets in the List // the mini-window has to do dragging and zooming, or taking itself to the selected places automatically // using some kind of max on a chosen path. // make the text update when we hit % as well as /, or after a delay. Maybe only text (not numbers) should not update // mode to draw only the station name (use lastIndexOf(".")) // pitch undercut to put the invisible path below; (take out and put in the pitch boundary) // remember to update the version of tunnel in TN.java each time // frame-sketch do all should update all of current image first (so one click operation) // multiple threads on the symbols layout for speed! // 1) Change of type to connective/centreline to be implemented by deleting and adding the line. // (maybe this should apply to all line changes, including splined -- just like the reflect type) // 2) Make area update no longer happen, because it's updated each time we add in a line // 3) Then areas are constant, and we can build symbols as they happen in an on-going thread (when the update symbols button is down) // 4) The znodes updates merely re-orders the lists of areas // 5) major update would happen when we change the subset style and bring in different symbols // 6) create new lists rather than clearing them as this will be thread safe // make area updates make areas rebuild automatically -- not just taking them out. Count them for verification against current version // make the Java3d Y for Z conversion // update node z to // what about the z height things // repaint the miniview when we get a new background // import new downsketch doesn't update the subsets see FillAllMissingAttributes and maketreerootnode to debug this // build the more sophisticated elevdev to handle multiple sequences. get working on this. // Ability to move individual nodes (not the ends) later. Prob do them separately. // other errors: // when you change a line from centreline to wall type it doesn't update the left-right kaareas! Must be implemented by deleting and making new // null pointer problems if you select Sketch from frame view and nothing is selected // move the SketchGraphics.elevpoint and other stuff into here // XC values should just work by direct line of sight // and have a linear over-lay along the XC. // closest direct centreline functions // extract the height values in the centrelines // zlev connective lines should be respected (does this come in with the update z?) // check the loading and saving of these files // check we can import sketches with elevations and XC sections without ruining them // (must account for subset duplicates) // max on sub view for a cross section or something, so we can go there quickly. // what do the setnodes in the info panel do? // do the map overlay upload. ///////////////////////////////////////////// ///////////////////////////////////////////// // this is a member of SelectedSubsetStructure and exists in partial (invalid) form, having to account for when // (a) more paths are added to the subset, or (b) when the selected subset changes class ElevSet { String selevsubset = null; List connsequence = new ArrayList(); List elevcenpaths = new ArrayList(); // will be one path when true. should have the number of line segments equal to the size of connsequence List elevpaths = new ArrayList(); boolean bIsElevStruct = false; boolean bXC; // for drawing the cursor mark List sscratchpaths = null; // will be parallel to connsequence double totalpathlength; ///////////////////////////////////////////// ElevSet() {;} ElevSet(String lselevsubset) { selevsubset = lselevsubset; bXC = selevsubset.substring(0, 2).equals("XC"); } ///////////////////////////////////////////// void Clear() { connsequence.clear(); elevcenpaths.clear(); elevpaths.clear(); bIsElevStruct = false; } ///////////////////////////////////////////// void AddRemovePath(OnePath op, boolean bAdd) { List lcat; if ((op.linestyle == SketchLineStyle.SLS_CONNECTIVE) && (op.plabedl != null) && (op.plabedl.barea_pres_signal == SketchLineStyle.ASE_ELEVATIONPATH)) lcat = connsequence; else if (op.linestyle == SketchLineStyle.SLS_CENTRELINE) lcat = elevcenpaths; else lcat = elevpaths; if (bAdd) { if (!lcat.contains(op)) lcat.add(op); } else lcat.remove(op); } ///////////////////////////////////////////// boolean SetIsElevStruct(boolean bsetpathlengths) { bIsElevStruct = ((selevsubset != null) && ReorderElevPaths(connsequence) && (elevcenpaths.size() == 1)); if (!bIsElevStruct) return false; if (bsetpathlengths) SetupPathLength(); bXC = selevsubset.substring(0, 2).equals("XC"); return true; } ///////////////////////////////////////////// void SetupPathLength() { if (sscratchpaths == null) sscratchpaths = new ArrayList(); totalpathlength = 0.0; for (int i = 0; i < connsequence.size(); i++) { if (i >= sscratchpaths.size()) sscratchpaths.add(new SSymbScratchPath()); sscratchpaths.get(i).SetUpPathLength(connsequence.get(i)); totalpathlength += sscratchpaths.get(i).GetCumuPathLength(); } } ///////////////////////////////////////////// static Point2D evalpt = new Point2D.Float(); static Point2D evalpttan = new Point2D.Float(); // this wants to set a triangle/arrow void AlongCursorMark(GeneralPath elevarrow, Ellipse2D elevpoint, Point2D moupt) { assert bIsElevStruct; OnePath cop = elevcenpaths.get(0); double x0 = elevcenpaths.get(0).pnstart.pn.getX(); double x1 = elevcenpaths.get(elevcenpaths.size() - 1).pnend.pn.getX(); Point2D c0 = connsequence.get(0).pnstart.pn; Point2D c1 = connsequence.get(connsequence.size() - 1).pnend.pn; double vcenX = x1 - x0; double lam = (vcenX != 0.0 ? (moupt.getX() - x0) / vcenX : 0.5); lam = (lam >= 0.0 ? (lam <= 1.0 ? lam : 1.0) : 0.0); Point2D levalpt = null; if (bXC) { evalpttan.setLocation(c1.getX() - c0.getX(), c1.getY() - c0.getY()); evalpt.setLocation(c0.getX() * (1.0 - lam) + c1.getX() * lam, c0.getY() * (1.0 - lam) + c1.getY() * lam); levalpt = evalpt; } else { double r = totalpathlength * lam; for (int i = 0; i < connsequence.size(); i++) { OnePath opc = connsequence.get(i); if ((r < sscratchpaths.get(i).GetCumuPathLength()) || (i == connsequence.size() - 1)) { double t = sscratchpaths.get(i).ConvertAbstoNodePathLength(r, opc); opc.Eval(evalpt, evalpttan, t); levalpt = evalpt; break; } r -= sscratchpaths.get(i).GetCumuPathLength(); } } double lstrokew = SketchLineStyle.strokew * 1.5; elevpoint.setFrame(levalpt.getX() - 2 * lstrokew, levalpt.getY() - 2 * lstrokew, 4 * lstrokew, 4 * lstrokew); double tanlen = Math.sqrt(evalpttan.getX() * evalpttan.getX() + evalpttan.getY() * evalpttan.getY()); // no document to refer to to find the leng function elevarrow.reset(); double xp = levalpt.getX(); double yp = levalpt.getY(); double xv = evalpttan.getX() / tanlen * lstrokew * 4; double yv = evalpttan.getY() / tanlen * lstrokew * 4; elevarrow.moveTo((float)xp, (float)yp); elevarrow.lineTo((float)(xp - xv - yv), (float)(yp - yv + xv)); elevarrow.lineTo((float)(xp - xv + yv), (float)(yp - yv - xv)); elevarrow.lineTo((float)xp, (float)yp); // for now add in the XC cut line if (bXC) { elevarrow.moveTo((float)c0.getX(), (float)c0.getY()); elevarrow.lineTo((float)c1.getX(), (float)c1.getY()); } } ///////////////////////////////////////////// OnePath MakeElevAxisPath(String sselevsubset, boolean lbXC, OnePathNode opcfore, OnePathNode opcback) { selevsubset = sselevsubset; bXC = lbXC; assert bXC == selevsubset.substring(0, 2).equals("XC"); SetupPathLength(); double opcpathleng = 0.0; double xmax = connsequence.get(0).pnstart.pn.getX(); for (OnePath opc : connsequence) { opc.plabedl.barea_pres_signal = SketchLineStyle.ASE_ELEVATIONPATH; // just now need to find where it is in the list in the combo-box opc.plabedl.iarea_pres_signal = SketchLineStyle.iareasigelev; if (SketchLineStyle.iareasigelev == -1) TN.emitError("Missing area_signal_def elevationpath in fontcolours"); assert opc.plabedl.barea_pres_signal == SketchLineStyle.areasigeffect[opc.plabedl.iarea_pres_signal]; xmax = Math.max(xmax, opc.pnend.pn.getX()); } double slx = connsequence.get(connsequence.size() - 1).pnend.pn.getX() - connsequence.get(0).pnstart.pn.getX(); double sly = connsequence.get(connsequence.size() - 1).pnend.pn.getY() - connsequence.get(0).pnstart.pn.getY(); double dstraightlensq = slx * slx + sly * sly; double dstraightlen = Math.sqrt(dstraightlensq); // now we're ready to go through with it //sketchdisplay.sketchlinestyle.SetConnectiveParametersIntoBoxes(opc); // make the centreline that will be added // this has nodes along it. // the nodes and endpoints could be displaced in y according to the z-values of the ends and mid-nodes // to enable complex contours of the sides of vertical pitches which may have multiple horizontal cross-sections all the way down. OnePath opelevaxis; OnePathNode cpnstart; OnePathNode cpnend; if (bXC) { // find the length double xright = xmax + totalpathlength / 2; double ylast = connsequence.get(connsequence.size() - 1).pnend.pn.getY(); //double opcpathlengH = (opc.pnstart.pn.getX() < opc.pnend.pn.getX() ? opcpathleng : -opcpathleng) / 2; cpnstart = new OnePathNode((float)(xright), (float)ylast, 0.0F); cpnend = new OnePathNode((float)(xright + dstraightlen), (float)ylast, 0.0F); //double opcpathlengH = (opc.pnstart.pn.getX() < opc.pnend.pn.getX() ? opcpathleng : -opcpathleng) / 2; } // elevation case. try to connect to a node that's already there else { //OnePathNode opcfore = connsequence.get(0).pnstart.ConnectingCentrelineNode(); //OnePathNode opcback = connsequence.get(connsequence.size() - 1).pnend.ConnectingCentrelineNode(); double xright = 50.0; cpnstart = new OnePathNode((float)(xright + 0.0), -(float)opcfore.zalt, 0.0F); cpnend = new OnePathNode((float)(xright + totalpathlength), -(float)opcback.zalt, 0.0F); //return; // not done yet } // now make the axis (inserting nodes along the way that can be flagged) opelevaxis = new OnePath(cpnstart); double lopcpathleng = sscratchpaths.get(0).GetCumuPathLength(); double z0 = (opcfore != null ? opcfore.zalt : connsequence.get(0).pnstart.zalt); for (int i = 1; i < connsequence.size(); i++) { OnePath opc = connsequence.get(i); OnePathNode opcc = opc.pnstart.ConnectingCentrelineNode(); // will have to account for zdisp too if (opcc == null) opcc = opc.pnstart; double lam; if (bXC) { double dslx = opc.pnstart.pn.getX() - connsequence.get(0).pnstart.pn.getX(); double dsly = opc.pnstart.pn.getY() - connsequence.get(0).pnstart.pn.getY(); double dd = dslx * slx + dsly * sly; lam = dd / dstraightlensq; } else { lam = lopcpathleng / totalpathlength; } double lx = cpnstart.pn.getX() * (1.0 - lam) + cpnend.pn.getX() * lam; double ly = cpnstart.pn.getY() * (1.0 - lam) + cpnend.pn.getY() * lam; // resetting ly so we get jagged path which may corresp to horizontally displaced centreline // requires update znodes to be done first ly = cpnstart.pn.getY() - (opcc.zalt - z0); // remember the ys go down opelevaxis.LineTo((float)lx, (float)ly); lopcpathleng += sscratchpaths.get(i).GetCumuPathLength(); } opelevaxis.EndPath(cpnend); opelevaxis.linestyle = SketchLineStyle.SLS_CENTRELINE; opelevaxis.plabedl = new PathLabelDecode(); opelevaxis.plabedl.centrelineelev = selevsubset; return opelevaxis; } ///////////////////////////////////////////// static void ExchangePaths(List oplist, int i, int j) { if (i == j) return; OnePath op = oplist.get(i); oplist.set(i, oplist.get(j)); oplist.set(j, op); } ///////////////////////////////////////////// static boolean ReorderElevPaths(List lopelevarr) { int nelevs = lopelevarr.size(); // first find the front node int ifront = -1; for (int i = 0; i < nelevs; i++) { boolean bfrontunique = true; for (int j = 0; j < nelevs; j++) { if (lopelevarr.get(i).pnstart == lopelevarr.get(j).pnend) bfrontunique = false; } if (bfrontunique) { if (ifront != -1) return false; ifront = i; } } if (ifront == -1) return false; ExchangePaths(lopelevarr, 0, ifront); // now find the joining pieces for (int i = 1; i < nelevs; i++) { int Lj = -1; for (int j = i; j < nelevs; j++) { if (lopelevarr.get(j).pnstart == lopelevarr.get(i - 1).pnend) { if (Lj != -1) return false; Lj = j; } } if (Lj == -1) return false; ExchangePaths(lopelevarr, i, Lj); } for (int i = 0; i < nelevs; i++) System.out.println(" elevccccc " + lopelevarr.get(i).pnstart + " " + lopelevarr.get(i).pnend); return true; } ///////////////////////////////////////////// // this will be more wide-ranging or test with static List IsElevationNode(OnePathNode wopn) { boolean belevnode = false; RefPathO srefpathconn = new RefPathO(); srefpathconn.ccopy(wopn.ropconn); do { if (srefpathconn.op.IsElevationCentreline()) belevnode = true; } while (!srefpathconn.AdvanceRoundToNode(wopn.ropconn)); //boolean bres = (bIsElevStruct && ((wopn == opelevarr.get(iopelevarrCEN).pnstart) || (wopn == opelevarr.get(iopelevarrCEN).pnend))); //System.out.println("Elevnodedetector " + belevnode + " " + bres); if (!belevnode) return null; // this looks for the entire connected component associated with this elevation node List elevcenconn = new ArrayList(); List vpnstack = new ArrayList(); List vpnused = new ArrayList(); vpnstack.add(wopn); vpnused.add(wopn); while (!vpnstack.isEmpty()) { OnePathNode opn = vpnstack.remove(vpnstack.size() - 1); srefpathconn.ccopy(opn.ropconn); do { if (srefpathconn.op.IsElevationCentreline()) { if (!elevcenconn.contains(srefpathconn.op)) elevcenconn.add(srefpathconn.op); OnePathNode oopn = (srefpathconn.op.pnstart == opn ? srefpathconn.op.pnend : srefpathconn.op.pnstart); if (!vpnused.contains(oopn)) { vpnstack.add(oopn); vpnused.add(oopn); } } } while (!srefpathconn.AdvanceRoundToNode(opn.ropconn)); } return elevcenconn; } }; ///////////////////////////////////////////// class ElevWarp { // has to account for liopelevarrCEN not always being 1 // make this run // reorder for each of these lists // make sure it covers // make a node mapping for every path that connects to it that's in the movable subsets // move the elevations transitively. Map elevconnmap = new HashMap(); Map elevwarppiecemap = new HashMap(); List warpfromcnodes = new ArrayList(); List warptocnodes = new ArrayList(); // collect all the components which make up the elevation boolean MakeElevWarp(List elevcenconn, List vpaths) { // not as effectively coded as poss, but I'm lacking the docs for the classes Set clsubsets = new HashSet(); // find the subsets represented by the centrelines that connect to the chosen node for (OnePath opc : elevcenconn) { assert opc.IsElevationCentreline(); for (String ssubset : opc.vssubsets) clsubsets.add(ssubset); } // allocate an elevation subset for each one for (String ssubset : clsubsets) elevconnmap.put(ssubset, new ElevSet(ssubset)); // allocate the paths into the subsets for (OnePath op : vpaths) { for (String ssubset : op.vssubsets) { if (clsubsets.contains(ssubset)) elevconnmap.get(ssubset).AddRemovePath(op, true); } } // go through and lose the connective lines parts from these sets for (String ssubset : clsubsets) { if (!elevconnmap.get(ssubset).SetIsElevStruct(false)) elevconnmap.remove(ssubset); } System.out.println("ggggggggg " + elevconnmap.size() + " " + clsubsets.size() + " " + elevconnmap.keySet().size()); boolean bres = true; for (OnePath opc : elevcenconn) { boolean bcpathaccounted = false; for (ElevSet elevset : elevconnmap.values()) { if (elevset.elevcenpaths.contains(opc)) bcpathaccounted = true; } if (!bcpathaccounted) bres = false; } return bres; } ///////////////////////////////////////////// // makes warpfromcnodes. another function could make a more global change void MakeWarpPathPieceMap(OnePath warppath) { for (String ssubset : elevconnmap.keySet()) { ElevSet elevset = elevconnmap.get(ssubset); assert elevset.bIsElevStruct; OnePath opc = elevset.elevcenpaths.get(0); assert opc.IsElevationCentreline(); // only include the nodes one a line that will be moved if (!((opc.pnstart == warppath.pnstart) || (opc.pnend == warppath.pnstart))) continue; OnePathNode npnstart = (opc.pnstart == warppath.pnstart ? warppath.pnend : opc.pnstart); OnePathNode npnend = (opc.pnend == warppath.pnstart ? warppath.pnend : opc.pnend); elevwarppiecemap.put(ssubset, new WarpPiece(opc.pnstart, opc.pnend, npnstart, npnend)); } assert warpfromcnodes.size() == warptocnodes.size(); //elevwarppiecemap } ///////////////////////////////////////////// Point2D ptspare = new Point2D.Float(); Set ssubsetsspare = new HashSet(); RefPathO srefpathconnspare = new RefPathO(); Set pthstowarp = new HashSet(); ///////////////////////////////////////////// OnePathNode WarpElevationNode(OnePathNode opn) { int ind = warpfromcnodes.indexOf(opn); if (ind != -1) return warptocnodes.get(ind); // find the subsets this node could be in srefpathconnspare.ccopy(opn.ropconn); do { ssubsetsspare.addAll(srefpathconnspare.op.vssubsets); } while (!srefpathconnspare.AdvanceRoundToNode(opn.ropconn)); // find the average displacement for the sums double xsum = 0.0; double ysum = 0.0; int nsum = 0; for (String ssubset : ssubsetsspare) { WarpPiece ewp = elevwarppiecemap.get(ssubset); if (ewp == null) continue; ewp.WarpPoint(ptspare, opn.pn.getX(), opn.pn.getY()); xsum += ptspare.getX(); ysum += ptspare.getY(); nsum++; } ssubsetsspare.clear(); OnePathNode opnto; if (nsum != 0) opnto = new OnePathNode((float)(xsum / nsum), (float)(ysum / nsum), opn.zalt); else opnto = opn; warpfromcnodes.add(opn); warptocnodes.add(opnto); System.out.println(" nnnn " + nsum); return opnto; } ///////////////////////////////////////////// void MakeWarpPathNodeslists() { // central warping of pieces for (WarpPiece ewp : elevwarppiecemap.values()) { if (!warpfromcnodes.contains(ewp.pnstart)) { warpfromcnodes.add(ewp.pnstart); warptocnodes.add(ewp.npnstart); } if (!warpfromcnodes.contains(ewp.pnend)) { warpfromcnodes.add(ewp.pnend); warptocnodes.add(ewp.npnend); } } } ///////////////////////////////////////////// void WarpAllPaths(List pthstoremove, List pthstoadd, OnePath warppath) { for (String ssubset : elevconnmap.keySet()) { ElevSet elevset = elevconnmap.get(ssubset); pthstowarp.addAll(elevset.elevcenpaths); // one entry pthstowarp.addAll(elevset.elevpaths); } pthstowarp.remove(warppath); for (OnePath op : pthstowarp) { OnePathNode nopnstart = WarpElevationNode(op.pnstart); OnePathNode nopnend = WarpElevationNode(op.pnend); if ((nopnstart == op.pnstart) && (nopnend == op.pnend)) continue; float[] pco = op.GetCoords(); OnePath nop = new OnePath(nopnstart); WarpPiece lewp = new WarpPiece(op.pnstart, op.pnend, nopnstart, nopnend); for (int i = 1; i < op.nlines; i++) { lewp.WarpPoint(ptspare, pco[i * 2], pco[i * 2 + 1]); nop.LineTo((float)ptspare.getX(), (float)ptspare.getY()); } nop.EndPath(nopnend); nop.CopyPathAttributes(op); pthstoremove.add(op); pthstoadd.add(nop); } } }; tunnelx-20140102.orig/src/LegLineFormat.java0000644000000000000000000006506712261213471015426 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.util.List; import java.util.ArrayList; // // // LegLineFormat // // public class LegLineFormat// implements Cloneable { static int DEGREES = 0; static int GRADS = 1; static int PERCENT = 2; static float TAPEFAC_M = 1.0F; static float TAPEFAC_CM = 0.01F; static float TAPEFAC_FT = 0.3048F; String datatype = "normal"; // or diving, cartesian, nosurvey, passage boolean bnosurvey = false; boolean bcartesian = false; boolean bbaddataline = false; boolean bpassage = false; boolean bsurface = false; boolean bduplicate = false; boolean bsplay = false; int fromindex = 0; int toindex = 1; int tapeindex = 2; float tapenegoffset = 0.0F; float tapefac = 1.0F; int compassindex = 3; int backcompassindex = -1; float compassnegoffset = 0.0F; float backcompassnegoffset = 0.0F; float compassnegoffsetdeclination = 0.0F; // a secondary offset value (separates the calibration from the magnetic wandering (declination)) int compassfac = DEGREES; int clinoindex = 4; int backclinoindex = -1; float clinonegoffset = 0.0F; int clinofac = DEGREES; int dxindex = -1; int dyindex = -1; int dzindex = -1; float dxfac = 1.0F; float dyfac = 1.0F; float dzfac = 1.0F; int depthindex = -1; int fromdepthindex = -1; int todepthindex = -1; float depthnegoffset = 0; float depthfac = 1.0F; int stationindex = -1; int leftindex = -1; int rightindex = -1; int upindex = -1; int downindex = -1; // this tells where the newline can be fit into the format // (to account for those two-line type records). int newlineindex = -1; String sdecimal = null; String sblank = null; // this may need to be mapped into the word splitter. String snames = null; // attributes carried over from those crappy blank begin blocks that are completely crap! String bb_svxdate = ""; String bb_svxtitle = ""; String bb_teamtape = ""; String bb_teampics = ""; String bb_teaminsts = ""; String bb_teamnotes = ""; List totalteam = new ArrayList(); StringBuffer sb_totalteam = new StringBuffer(); // local data used for multi-line (diving) type data. String lstation = null; float ldepth = 0; float lcompass = 0; float ltape = 0; float ldx = 0; float ldy = 0; float ldz = 0; boolean btopextendedelevation = false; boolean btopextflipleg = false; int currnewlineindex = 0; FileAbstraction currfile; ///////////////////////////////////////////// LegLineFormat() // constructs the default one. {;} ///////////////////////////////////////////// LegLineFormat(LegLineFormat f) { if (f != null) { datatype = f.datatype; bnosurvey = f.bnosurvey; bcartesian = f.bcartesian; bpassage = f.bpassage; bsurface = f.bsurface; bduplicate = f.bduplicate; bsplay = f.bsplay; bbaddataline = f.bbaddataline; fromindex = f.fromindex; toindex = f.toindex; tapeindex = f.tapeindex; tapenegoffset = f.tapenegoffset; tapefac = f.tapefac; compassindex = f.compassindex; backcompassindex = f.backcompassindex; compassnegoffset = f.compassnegoffset; backcompassnegoffset = f.backcompassnegoffset; compassnegoffsetdeclination = f.compassnegoffsetdeclination; compassfac = f.compassfac; clinoindex = f.clinoindex; backclinoindex = f.backclinoindex; clinonegoffset = f.clinonegoffset; clinofac = f.clinofac; dxindex = f.dxindex; dyindex = f.dyindex; dzindex = f.dzindex; dxfac = f.dxfac; dyfac = f.dyfac; dzfac = f.dzfac; newlineindex = f.newlineindex; stationindex = f.stationindex; depthindex = f.depthindex; fromdepthindex = f.fromdepthindex; todepthindex = f.todepthindex; depthnegoffset = f.depthnegoffset; depthfac = f.depthfac; leftindex = f.leftindex; rightindex = f.rightindex; upindex = f.upindex; downindex = f.downindex; sdecimal = f.sdecimal; sblank = f.sblank; snames = f.snames; btopextendedelevation = f.btopextendedelevation; bb_svxdate = f.bb_svxdate; bb_svxtitle = f.bb_svxtitle; bb_teamtape = f.bb_teamtape; bb_teampics = f.bb_teampics; bb_teaminsts = f.bb_teaminsts; bb_teamnotes = f.bb_teamnotes; UpdateTotalTeam(); } } ///////////////////////////////////////////// void AddToTotalTeam(String steam) { if (steam.length() == 0) return; if (steam.equalsIgnoreCase("both") || steam.equalsIgnoreCase("none")) return; int iand = steam.indexOf(" and "); if (iand != -1) { AddToTotalTeam(steam.substring(0, iand)); AddToTotalTeam(steam.substring(iand + 5)); return; } int iand1 = steam.indexOf("&"); if (iand1 == -1) iand1 = steam.indexOf("+"); if (iand1 == -1) iand1 = steam.indexOf(","); if (iand1 != -1) { AddToTotalTeam(steam.substring(0, iand1).trim()); AddToTotalTeam(steam.substring(iand1 + 1).trim()); return; } steam = steam.trim(); for (String lteam : totalteam) if (steam.equalsIgnoreCase(lteam)) return; totalteam.add(steam); } ///////////////////////////////////////////// void UpdateTotalTeam() { totalteam.clear(); AddToTotalTeam(bb_teamnotes); AddToTotalTeam(bb_teampics); AddToTotalTeam(bb_teaminsts); AddToTotalTeam(bb_teamtape); sb_totalteam.setLength(0); for (String t : totalteam) { if (sb_totalteam.length() != 0) sb_totalteam.append(", "); sb_totalteam.append(t); } } ///////////////////////////////////////////// public String toString() { StringBuffer sb = new StringBuffer(); sb.append(datatype); int im0 = Math.max(fromindex, toindex); int im1 = Math.max(clinoindex, compassindex); int im2 = Math.max(backclinoindex, backcompassindex); int im3 = tapeindex; int im = Math.max(Math.max(im0, im1), Math.max(im2, im3)); for (int i = 0; i <= im; i++) { if (i == fromindex) sb.append(" from"); else if (i == toindex) sb.append(" to"); else if (i == tapeindex) sb.append(" tape"); else if (i == compassindex) sb.append(" compass"); else if (i == clinoindex) sb.append(" clino"); else if (i == backcompassindex) sb.append(" backcompass"); else if (i == backclinoindex) sb.append(" backclino"); else if (i == dxindex) sb.append(" dx"); else if (i == dyindex) sb.append(" dy"); else if (i == dzindex) sb.append(" dz"); else if (i == depthindex) sb.append(" depth"); else if (i == fromdepthindex) sb.append(" fromdepth"); else if (i == todepthindex) sb.append(" todepth"); else if (i == stationindex) sb.append(" station"); else if (i == newlineindex) sb.append(" newline"); else if (i == leftindex) sb.append(" left"); else if (i == rightindex) sb.append(" right"); else if (i == upindex) sb.append(" up"); else if (i == downindex) sb.append(" down"); else sb.append(" ignore"); } sb.append(" ignoreall"); return sb.toString(); } ///////////////////////////////////////////// // this substitutes characters in these strings with ones that make them parsable. String ApplySet(String field) { // deal with the blank conversions. if (sblank != null) { for (int i = 0; i < sblank.length(); i++) field = field.replace(sblank.charAt(i), ' '); } // deal with the decimal conversions. if (sdecimal != null) { for (int i = 0; i < sdecimal.length(); i++) field = field.replace(sdecimal.charAt(i), '.'); } return field; } ///////////////////////////////////////////// float ReadCompass(String ws, boolean bback) { String acompass = ApplySet(ws); if (acompass.equalsIgnoreCase("-") || acompass.equals("")) return OneLeg.INVALID_COMPASSCLINO; float compass = GetFLval(acompass) - (bback ? backcompassnegoffset : compassnegoffset) - compassnegoffsetdeclination; if (compassfac == GRADS) compass *= 360.0F / 400.0F; while (compass < 0.0F) compass += 360.0F; while (compass > 360.0F) compass -= 360.0F; return compass; } ///////////////////////////////////////////// float ReadClino(String ws) { float clino; String aclino = ApplySet(ws); if (aclino.equalsIgnoreCase("-")) return OneLeg.INVALID_COMPASSCLINO; if (aclino.equalsIgnoreCase("up") || aclino.equalsIgnoreCase("u") || aclino.equalsIgnoreCase("+V")) clino = 90.0F; else if (aclino.equalsIgnoreCase("down") || aclino.equalsIgnoreCase("d") || aclino.equalsIgnoreCase("-V")) clino = -90.0F; else if (aclino.equalsIgnoreCase("h") || aclino.equalsIgnoreCase("level")) clino = 0.0F; else { clino = GetFLval(aclino); clino -= clinonegoffset; // is there a different setting for backclino? if (clinofac == GRADS) clino *= 360.0F / 400.0F; if (clinofac == PERCENT) clino = (float)TN.percentdeg(clino); } return clino; } ///////////////////////////////////////////// OneLeg ReadLeg(String w[], LineInputStream lis) { try { // normal leg format with everything there. if ((newlineindex == -1) && (stationindex == -1)) { if (w[toindex].equals("-")) return null; // discarding splay station if (w[toindex].startsWith("-") && w[toindex].endsWith("-")) return null; // discarding splay station // case of just a leg but with no measurements on it if (bnosurvey) return new OneLeg(w[fromindex], w[toindex], this); if (bbaddataline) { lis.emitWarning("ignoring line due to bad *data format"); return null; } if (bcartesian) { float dx = GetFLval(ApplySet(w[dxindex])) * dxfac; float dy = GetFLval(ApplySet(w[dyindex])) * dyfac; float dz = GetFLval(ApplySet(w[dzindex])) * dzfac; return new OneLeg(dx, dy, dz, w[fromindex], w[toindex], this); } String atape = ApplySet(w[tapeindex]); float tape = (GetFLval(atape) - tapenegoffset) * tapefac; float compass = ReadCompass(w[compassindex], false); float backcompass = (backcompassindex == -1 ? OneLeg.INVALID_COMPASSCLINO : ReadCompass(w[backcompassindex], true)); // clino data exists if (clinoindex != -1) { float clino = ReadClino(w[clinoindex]); float backclino = (backclinoindex == -1 ? OneLeg.INVALID_COMPASSCLINO : ReadClino(w[backclinoindex])); if ((compass == OneLeg.INVALID_COMPASSCLINO) && (backcompass == OneLeg.INVALID_COMPASSCLINO)) { if ((clino != -90.0F) && (clino != 90.0F)) TN.emitWarning("Error, blank compass on non-vertical leg " + w[0] + " " + w[1] + " " + w[2] + " " + w[3] + " " + w[4] + " " + w[5]); } if (btopextendedelevation) btopextflipleg = w[5].equals(TN.flipCLINEsignal); OneLeg ol = new OneLeg(w[fromindex], w[toindex], tape, compass, backcompass, clino, backclino, this); return ol; } else assert backclinoindex == -1; // case where clino not needed in diving data if ((fromdepthindex != -1) && (todepthindex != -1)) { String afromdepth = ApplySet(w[fromdepthindex]); float fromdepth = GetFLval(afromdepth); String atodepth = ApplySet(w[fromdepthindex]); float todepth = GetFLval(atodepth); TN.emitMessage("LDIVING " + w[fromindex] + " " + w[toindex] + " " + tape + " " + compass + " " + fromdepth + " " + todepth); if ((compass == OneLeg.INVALID_COMPASSCLINO) && (backcompass != OneLeg.INVALID_COMPASSCLINO)) // unlikely to do good backsights in diving data compass = backcompass; return new OneLeg(w[fromindex], w[toindex], tape, compass, fromdepth, todepth, this); } } // cope with some difficult format that spans more than one line. if ((stationindex != -1) && (newlineindex != -1)) { // load the station and build the return value if we have a follow on. int nextnewlineindex = (currnewlineindex == 0 ? newlineindex : w.length); String lnewstation = null; float lnewdepth = -1.0F; if ((stationindex < nextnewlineindex) && (stationindex >= currnewlineindex)) // currnewlineindex is 0 in this case. lnewstation = w[stationindex - currnewlineindex]; // probably assumes when depthindex == -1 it's not >= currnewlineindex if ((depthindex < nextnewlineindex) && (depthindex >= currnewlineindex)) // currnewlineindex is 0 in this case. { String adepth = ApplySet(w[depthindex - currnewlineindex]); lnewdepth = (GetFLval(adepth) + depthnegoffset) * depthfac; } // build the result. OneLeg olres = null; if ((lnewstation != null) && (lstation != null)) // and the rest. { if (bcartesian) { olres = new OneLeg(ldx, ldy, ldz, lstation, lnewstation, this); TN.emitMessage("DIVING cart " + lstation + " " + lnewstation + " " + ltape + " " + lcompass + " " + ldepth + " " + lnewdepth); } else { olres = new OneLeg(lstation, lnewstation, ltape, lcompass, ldepth, lnewdepth, this); TN.emitMessage("DIVING " + lstation + " " + lnewstation + " " + ltape + " " + lcompass + " " + ldepth + " " + lnewdepth); } // should clear all the fields. } // copy over the new labels. if (lnewstation != null) { lstation = lnewstation; ldepth = lnewdepth; } // get tape and compass. if ((tapeindex < nextnewlineindex) && (tapeindex >= currnewlineindex)) // currnewlineindex is 0 in this case. { String atape = ApplySet(w[tapeindex - currnewlineindex]); ltape = (GetFLval(atape) + tapenegoffset) * tapefac; } if ((compassindex < nextnewlineindex) && (compassindex >= currnewlineindex)) // currnewlineindex is 0 in this case. { String acompass = ApplySet(w[compassindex - currnewlineindex]); boolean bcblank = (acompass.equalsIgnoreCase("-") || acompass.equals("")); lcompass = (bcblank ? 0.0F : GetFLval(acompass)) - compassnegoffset - compassnegoffsetdeclination; if (compassfac == GRADS) lcompass *= 360.0F / 400.0F; } if (bcartesian) { if ((dxindex < nextnewlineindex) && (dxindex >= currnewlineindex)) ldx = GetFLval(ApplySet(w[dxindex - currnewlineindex])) * dxfac; if ((dyindex < nextnewlineindex) && (dyindex >= currnewlineindex)) ldy = GetFLval(ApplySet(w[dyindex - currnewlineindex])) * dyfac; if ((dzindex < nextnewlineindex) && (dzindex >= currnewlineindex)) ldz = GetFLval(ApplySet(w[dzindex - currnewlineindex])) * dzfac; } // update the lineindex. currnewlineindex = (currnewlineindex == 0 ? (newlineindex + 1) : 0); // not properly implemented case (errors not mapping across lines). return olres; } // we should be loading these in as cross-section objects if (datatype.equalsIgnoreCase("passage")) { //System.out.println("PASSAGE:: " + lis.GetLine()); return null; } TN.emitWarning("Can't do format " + datatype); } catch (NumberFormatException e) { lis.emitError("Number Format"); } return null; } ///////////////////////////////////////////// OneLeg ReadFix(String w[], LineInputStream lis) { try { int i = (w[2].equalsIgnoreCase("reference") ? 3 : 2); float fx = GetFLval(w[i]) * tapefac; float fy = GetFLval(w[i + 1]) * tapefac; float fz = GetFLval(w[i + 2]) * tapefac; return new OneLeg(w[1], fx, fy, fz, this); // fix type } catch (NumberFormatException e) { lis.emitError("Number Format"); } return null; } ///////////////////////////////////////////// public void StarCalibrate(String scaltype, String scalval, String sfacval, LineInputStream lis) { try { float fval = GetFLval(scalval); if (scaltype.equalsIgnoreCase("tape")) tapenegoffset = fval * tapefac; else if (scaltype.equalsIgnoreCase("compass")) compassnegoffset = fval; else if (scaltype.equalsIgnoreCase("backcompass")) backcompassnegoffset = fval; else if (scaltype.equalsIgnoreCase("declination")) compassnegoffsetdeclination = fval; else if (scaltype.equalsIgnoreCase("clino") || scaltype.equalsIgnoreCase("clinometer")) clinonegoffset = fval; else if (scaltype.equalsIgnoreCase("depth")) { depthnegoffset = fval; if (!sfacval.equals("")) { float facval = GetFLval(sfacval); depthfac = facval; } } else TN.emitWarning("bad *Calibrate type " + scaltype); } catch (NumberFormatException e) { lis.emitError("Number Format"); } } ///////////////////////////////////////////// float GetFLval(String s) { if (s.equals("+0_0")) return 0.0F; float res = Float.parseFloat(s); return res; } ///////////////////////////////////////////// public void StarUnits(String sunitype, String sunitval1, String sunitval2, LineInputStream lis) { String sunitval = sunitval1; float fac = 1.0F; if (!sunitval2.equals("")) { sunitval = sunitval2; fac = GetFLval(sunitval1); } if (sunitype.equalsIgnoreCase("length") || sunitype.equalsIgnoreCase("tape")) { if (sunitval.equalsIgnoreCase("metres") || sunitval.equalsIgnoreCase("meters")) tapefac = TAPEFAC_M * fac; else if (sunitval.equalsIgnoreCase("cm")) tapefac = TAPEFAC_CM * fac; else if (sunitval.equalsIgnoreCase("feet")) tapefac = TAPEFAC_FT * fac; else TN.emitWarning("don't know *Units length " + sunitval1 + "," + sunitval2); } else if (sunitype.equalsIgnoreCase("bearing") || sunitype.equalsIgnoreCase("compass")) { assert sunitval2.equals("") || (fac == 1.0); if (sunitval.equalsIgnoreCase("degrees")) compassfac = DEGREES; else if (sunitval.equalsIgnoreCase("grads")) compassfac = GRADS; else TN.emitWarning("don't know *Units bearing " + sunitval1 + "," + sunitval2); } else if (sunitype.equalsIgnoreCase("gradient") || sunitype.equalsIgnoreCase("clino")) { assert sunitval2.equals("") || (fac == 1.0); if (sunitval.equalsIgnoreCase("degrees")) clinofac = DEGREES; else if (sunitval.equalsIgnoreCase("grads")) clinofac = GRADS; else if (sunitval.equalsIgnoreCase("percent")) clinofac = PERCENT; else TN.emitWarning("don't know *Units gradient " + sunitval1 + "," + sunitval2); } else if (sunitype.equalsIgnoreCase("dx")) { if (sunitval.equalsIgnoreCase("metres") || sunitval.equalsIgnoreCase("meters")) dxfac = TAPEFAC_M * fac; else TN.emitWarning("don't know *Units dx " + sunitval1 + "," + sunitval2); } else if (sunitype.equalsIgnoreCase("dy")) { if (sunitval.equalsIgnoreCase("metres") || sunitval.equalsIgnoreCase("meters")) dyfac = TAPEFAC_M * fac; else TN.emitWarning("don't know *Units dy " + sunitval1 + "," + sunitval2); } else if (sunitype.equalsIgnoreCase("dz")) { if (sunitval.equalsIgnoreCase("metres") || sunitval.equalsIgnoreCase("meters")) dzfac = TAPEFAC_M * fac; else TN.emitWarning("don't know *Units dz " + sunitval1 + "," + sunitval2); } else TN.emitWarning("don't know *Units type: " + sunitype); } ///////////////////////////////////////////// public void StarSet(String sfield, String setting, LineInputStream lis) { if (sfield.equalsIgnoreCase("decimal")) sdecimal = setting; else if (sfield.equalsIgnoreCase("blank")) sblank = setting; else if (sfield.equalsIgnoreCase("names")) snames = setting; else TN.emitWarning("don't know *set " + sfield + " " + setting); } ///////////////////////////////////////////// public void StarFlags(String[] w, int iw) { int i = 1; boolean bflag = true; if (w[1].equalsIgnoreCase("not")) { bflag = false; i = 2; } if (w[i].equalsIgnoreCase("surface")) bsurface = bflag; else if (w[i].equalsIgnoreCase("duplicate")) bduplicate = bflag; else if (w[i].equalsIgnoreCase("duplicate")) bsplay = bflag; else if (w[i].equalsIgnoreCase("splay")) bsplay = bflag; else System.out.println(" unrecognized StarFlags " + w[1]); } ///////////////////////////////////////////// // This is programmed to work on the one known example of *Data. public boolean StarDataNormal(String[] w, int iw) { if (w[1].equalsIgnoreCase("default")) { w[1] = "normal"; w[2] = "from"; w[3] = "to"; w[4] = "tape"; w[5] = "compass"; w[6] = "clino"; iw = 7; } datatype = w[1]; bnosurvey = datatype.equalsIgnoreCase("nosurvey"); bcartesian = datatype.equalsIgnoreCase("cartesian"); bpassage = datatype.equalsIgnoreCase("normal") || datatype.equalsIgnoreCase("passage") || datatype.equalsIgnoreCase("diving"); if (!bnosurvey && !bcartesian && !bpassage) TN.emitError("Unrecognized *data command: " + datatype); bbaddataline = false; // first kill stupid - symbol people keep putting into their commands if (w[2].equals("-")) { TN.emitMessage("Removing stupid '-' symbol from *data Normal line"); for (int i = 3; i < iw; i++) w[i - 1] = w[i]; iw--; } int lfromindex = -1; int ltoindex = -1; int ltapeindex = -1; int lcompassindex = -1; int lclinoindex = -1; int lbackcompassindex = -1; int lbackclinoindex = -1; int ldxindex = -1; int ldyindex = -1; int ldzindex = -1; int lstationindex = -1; int lnewlineindex = -1; int ldepthindex = -1; int lfromdepthindex = -1; int ltodepthindex = -1; int lleftindex = -1; int lrightindex = -1; int lupindex = -1; int ldownindex = -1; int i; for (i = 2; i < iw; i++) { if (w[i].equalsIgnoreCase("from")) { if (lfromindex != -1) break; lfromindex = i - 2; } else if (w[i].equalsIgnoreCase("to")) { if (ltoindex != -1) break; ltoindex = i - 2; } else if (w[i].equalsIgnoreCase("length") || w[i].equalsIgnoreCase("tape")) { if (ltapeindex != -1) break; ltapeindex = i - 2; } else if (w[i].equalsIgnoreCase("compass") || w[i].equalsIgnoreCase("bearing")) { if (lcompassindex != -1) break; lcompassindex = i - 2; } else if (w[i].equalsIgnoreCase("backcompass") || w[i].equalsIgnoreCase("backbearing")) { if (lbackcompassindex != -1) break; lbackcompassindex = i - 2; } else if (w[i].equalsIgnoreCase("clino") || w[i].equalsIgnoreCase("gradient")) { if (lclinoindex != -1) break; lclinoindex = i - 2; } else if (w[i].equalsIgnoreCase("backclino") || w[i].equalsIgnoreCase("backgradient")) { if (lbackclinoindex != -1) break; lbackclinoindex = i - 2; } else if (w[i].equalsIgnoreCase("ignore")) ; else if (w[i].equalsIgnoreCase("ignoreall")) ; else if (w[i].equalsIgnoreCase("remarks")) ; else if (w[i].equalsIgnoreCase("newline")) { if (lnewlineindex != -1) break; lnewlineindex = i - 2; } else if (w[i].equalsIgnoreCase("dx") || w[i].equalsIgnoreCase("easting")) { if (ldxindex != -1) break; ldxindex = i - 2; } else if (w[i].equalsIgnoreCase("dy") || w[i].equalsIgnoreCase("northing")) { if (ldyindex != -1) break; ldyindex = i - 2; } else if (w[i].equalsIgnoreCase("dz") || w[i].equalsIgnoreCase("altitude")) { if (ldzindex != -1) break; ldzindex = i - 2; } // from becomes station. else if (w[i].equalsIgnoreCase("station")) { if (lstationindex != -1) break; lstationindex = i - 2; } else if (w[i].equalsIgnoreCase("depth")) { if (ldepthindex != -1) break; ldepthindex = i - 2; } else if (w[i].equalsIgnoreCase("fromdepth")) { if (lfromdepthindex != -1) break; lfromdepthindex = i - 2; } else if (w[i].equalsIgnoreCase("todepth")) { if (ltodepthindex != -1) break; ltodepthindex = i - 2; } else if (w[i].equalsIgnoreCase("left")) { if (lleftindex != -1) break; lleftindex = i - 2; } else if (w[i].equalsIgnoreCase("right")) { if (lrightindex != -1) break; lrightindex = i - 2; } else if (w[i].equalsIgnoreCase("up")) { if (lupindex != -1) break; lupindex = i - 2; } else if (w[i].equalsIgnoreCase("down")) { if (ldownindex != -1) break; ldownindex = i - 2; } else { TN.emitWarning("!!! " + w[i] + " " + i); break; } } // incomplete. if (i != iw) { bbaddataline = true; return false; } boolean bstandardform = ((lfromindex != -1) && (ltoindex != -1) && (ltapeindex != -1) && (lcompassindex != -1) && (lclinoindex != -1)); boolean bcartesianform = (bcartesian && (ldxindex != -1) && (ldyindex != -1) && (ldzindex != -1)); boolean bdivingform = ((ltapeindex != -1) && (lcompassindex != -1) && (ldepthindex != -1) && (lstationindex != -1) && (lnewlineindex != -1)); boolean bldivingform = ((lfromindex != -1) && (ltoindex != -1) && (ltapeindex != -1) && (lcompassindex != -1) && (lfromdepthindex != -1) && (ltodepthindex != -1)); boolean blpassageform = ((lstationindex != -1) && (lleftindex != -1) && (lrightindex != -1) && (lupindex != -1) && (ldownindex != -1)); boolean blbnosurvey = (bnosurvey && (lfromindex != -1) && (ltoindex != -1) && (ltapeindex == -1) && (lcompassindex == -1) && (lfromdepthindex == -1) && (ltodepthindex == -1)); // bad line if (!bstandardform && !bcartesianform && !bdivingform && !bldivingform && !blpassageform && !blbnosurvey) { TN.emitMessage("Indexes From " + lfromindex + " to " + ltoindex + " tape " + ltapeindex + " compass " + lcompassindex + " clino " + lclinoindex); bbaddataline = true; return false; } fromindex = lfromindex; toindex = ltoindex; tapeindex = ltapeindex; compassindex = lcompassindex; clinoindex = lclinoindex; backcompassindex = lbackcompassindex; backclinoindex = lbackclinoindex; dxindex = ldxindex; dyindex = ldyindex; dzindex = ldzindex; stationindex = lstationindex; depthindex = ldepthindex; fromdepthindex = lfromdepthindex; todepthindex = ltodepthindex; newlineindex = lnewlineindex; leftindex = lleftindex; rightindex = lrightindex; upindex = lupindex; downindex = ldownindex; bbaddataline = false; return true; } ///////////////////////////////////////////// ///////////////////////////////////////////// } tunnelx-20140102.orig/src/TodeNode.java0000644000000000000000000014016512261213471014430 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2010 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import javax.swing.JPanel; import javax.swing.JButton; import javax.swing.JToggleButton; import javax.swing.JTextField; import javax.swing.JLabel; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Color; import java.awt.geom.GeneralPath; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.geom.Line2D; import java.awt.geom.Ellipse2D; import java.awt.geom.AffineTransform; import java.awt.Shape; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.GridLayout; import java.util.List; import java.util.ArrayList; import java.util.Arrays; import java.util.Random; ///////////////////////////////////////////// class DoubleArray { double[] arr = null; int sz = 0; void add(double val) { if (arr == null) arr = new double[2]; else if (sz == arr.length) { double[] larr = arr; arr = new double[larr.length * 2]; for (int i = 0; i < larr.length; i++) arr[i] = larr[i]; } arr[sz] = val; sz++; } double pop() { sz--; return arr[sz]; } int size() { return sz; } double get(int i) { assert ((i >= 0) && (i < sz)); return arr[i]; } void sort() { if (sz != 0) Arrays.sort(arr, 0, sz); } public String toString() { StringBuffer sb = new StringBuffer(); for (int i = 0; i < sz; i++) sb.append((i == 0 ? "" : " ") + String.format("%.3f", get(i))); return sb.toString(); } public String toStringRel() { StringBuffer sb = new StringBuffer(); for (int i = 0; i < sz; i++) sb.append((i == 0 ? "" : " ") + String.format("%.3f", get(i) - get(0))); return sb.toString(); } } ///////////////////////////////////////////// ///////////////////////////////////////////// class IntensityWedge { double t0; double e0; double t1; double e1; double slope; IntensityWedge(double lt0, double le0, double lt1, double le1) { t0 = lt0; e0 = le0; t1 = lt1; e1 = le1; slope = (e1 - e0) / (t1 - t0); } ///////////////////////////////////////////// double GetIntensityW(double eT) { assert (t0 <= eT) && (eT <= t1); double lam = (eT - t0) / (t1 - t0); return e0 * (1.0 - lam) + e1 * lam; } ///////////////////////////////////////////// IntensityWedge(IntensityWedge rightwedge, double tsplit) { assert ((tsplit > rightwedge.t0) && (tsplit < rightwedge.t1)); t0 = rightwedge.t0; e0 = rightwedge.e0; t1 = tsplit; e1 = rightwedge.GetIntensityW(tsplit); slope = rightwedge.slope; assert VerifySlope(); rightwedge.t0 = tsplit; rightwedge.e0 = e1; assert rightwedge.VerifySlope(); } ///////////////////////////////////////////// boolean VerifySlope() { double slediff = Math.abs((t1 - t0) * slope - (e1 - e0)); if (slediff < 0.001) // for very small changes in e value return true; double lslope = (e1 - e0) / (t1 - t0); if (Math.abs(lslope - slope) <= 0.01) return true; System.out.println(this + " " + (t0 - t1) + " " + (e0 - e1) + " " + lslope + " " + slope); return false; } ///////////////////////////////////////////// double GetExponentialAvgW(double eT, double efac, double lt1) { assert ((lt1 > t0) && (lt1 <= t1)); // integral from t0 to lt1 of [(t - t0) + e0] exp((t - eT) efac) double b = Math.exp((lt1 - eT) * efac) * (lt1 * slope - slope / efac + (e0 - t0 * slope)) / efac; double a = Math.exp((t0 - eT) * efac) * (t0 * slope - slope / efac + (e0 - t0 * slope)) / efac; return b - a; } ///////////////////////////////////////////// public String toString() { return String.format("(%.3f,%.2f %.3f,%.2f)", t0, e0, t1, e1); } } ///////////////////////////////////////////// ///////////////////////////////////////////// class IntensityEnvelope { List wedges = new ArrayList(); double emin; double emax; double epeak = 0.0; double tpeak = 0.0; ///////////////////////////////////////////// double GetIntensity(double eT) { for (int i = 0; i < wedges.size(); i++) { if ((wedges.get(i).t0 <= eT) && (eT < wedges.get(i).t1)) return wedges.get(i).GetIntensityW(eT); } return 0.0; } ///////////////////////////////////////////// // not used double GetExponentialAverage(double eT, double efac) { double result = 0.0; for (int i = 0; i < wedges.size(); i++) { IntensityWedge wedge = wedges.get(i); if (wedge.t0 >= eT) break; result += wedge.GetExponentialAvgW(eT, efac, Math.min(eT, wedge.t1)); } return result; } ///////////////////////////////////////////// double GetLastPeak(double eT, double peakfac) { double peakexp = epeak * Math.exp((tpeak - eT) * peakfac); for (int i = 0; i < wedges.size(); i++) { IntensityWedge wedge = wedges.get(i); if (wedge.t0 >= eT) break; if (wedge.e0 > 0.0) { double e0exp = wedge.e0 * Math.exp((wedge.t0 - eT) * peakfac); if (e0exp > peakexp) { epeak = wedge.e0; tpeak = wedge.t0; peakexp = e0exp; } } if (wedge.t1 <= eT) { double e1exp = wedge.e1 * Math.exp((wedge.t1 - eT) * peakfac); if (e1exp > peakexp) { epeak = wedge.e1; tpeak = wedge.t1; peakexp = e1exp; } } else { double le1 = wedge.GetIntensityW(eT); double le1exp = le1; if (le1exp > peakexp) { epeak = le1; tpeak = eT; peakexp = le1exp; } } } return epeak; } ///////////////////////////////////////////// void SeteextremesL(double t, double e, boolean bFirst) { if (bFirst) { emin = e; emax = e; tpeak = t; } else if (e < emin) { emin = e; if (-emin > emax) tpeak = t; } else if (e > emax) { emax = e; if (emax > -emin) tpeak = t; } } void Seteextremes() { for (int i = 0; i < wedges.size(); i++) { IntensityWedge wedge = wedges.get(i); SeteextremesL(wedge.t0, wedge.e0, (i == 0)); SeteextremesL(wedge.t1, wedge.e1, false); } } ///////////////////////////////////////////// boolean VerifyWedges() { for (int i = 0; i < wedges.size(); i++) { assert wedges.get(i).VerifySlope(); assert wedges.get(i).t0 < wedges.get(i).t1; if (i != 0) assert wedges.get(i - 1).t1 <= wedges.get(i).t0; } return true; } ///////////////////////////////////////////// void AddWedge(IntensityWedge lnewwedge, double toffset) { // should build offset into the algorithm IntensityWedge newwedge = new IntensityWedge(lnewwedge.t0 + toffset, lnewwedge.e0, lnewwedge.t1 + toffset, lnewwedge.e1); newwedge.slope = newwedge.slope; newwedge.VerifySlope(); // verification measures double te0m = newwedge.t0 - 1.0; double ee0m = GetIntensity(te0m); double ee0 = GetIntensity(newwedge.t0) + newwedge.e0; double tehalf = newwedge.t0 * 0.6 + newwedge.t1 * 0.4; double eehalf = GetIntensity(tehalf) + newwedge.GetIntensityW(tehalf); double ten1 = newwedge.t0 * 0.001 + newwedge.t1 * 0.999; double een1 = GetIntensity(ten1) + newwedge.GetIntensityW(ten1); double ee1 = GetIntensity(newwedge.t1); double te1p = newwedge.t1 + 1.0; double ee1p = GetIntensity(te1p); AddWedgeV(newwedge); //System.out.println("Env: " + this); assert VerifyWedges(); // verification values assert Math.abs(ee0m - GetIntensity(te0m)) < 0.001; assert Math.abs(ee0 - GetIntensity(newwedge.t0)) < 0.001; assert Math.abs(eehalf - GetIntensity(tehalf)) < 0.001; assert Math.abs(een1 - GetIntensity(ten1)) < 0.001; assert Math.abs(ee1 - GetIntensity(newwedge.t1)) < 0.001; assert Math.abs(ee1p - GetIntensity(te1p)) < 0.001; } ///////////////////////////////////////////// void AddWedgeV(IntensityWedge newwedge) { // full outer wedge cases if ((wedges.size() == 0) || (wedges.get(wedges.size() - 1).t1 <= newwedge.t0)) { wedges.add(newwedge); return; } if (newwedge.t1 <= wedges.get(0).t0) { wedges.add(0, newwedge); return; } // find wedges int i0; for (i0 = 0; i0 < wedges.size(); i0++) { if (newwedge.t0 < wedges.get(i0).t1) break; } assert (i0 < wedges.size()); int i1; for (i1 = wedges.size() - 1; i1 >= 0; i1--) { if (wedges.get(i1).t0 < newwedge.t1) break; } // wedge in gap if (i1 == i0 - 1) { wedges.add(i0, newwedge); return; } assert (i0 <= i1); // create partial outer wedge left if (newwedge.t0 < wedges.get(i0).t0) { assert ((i0 == 0) || (wedges.get(i0 - 1).t1 <= newwedge.t0)); IntensityWedge outerwedge = new IntensityWedge(newwedge.t0, newwedge.e0, wedges.get(i0).t0, newwedge.GetIntensityW(wedges.get(i0).t0)); wedges.add(i0, outerwedge); i0++; i1++; } // split wedge left else if (newwedge.t0 > wedges.get(i0).t0) { IntensityWedge leftwedge = new IntensityWedge(wedges.get(i0), newwedge.t0); wedges.add(i0, leftwedge); i1++; i0++; assert VerifyWedges(); } // create partial outer wedge right if (wedges.get(i1).t1 < newwedge.t1) { assert ((i1 == wedges.size() - 1) || (newwedge.t1 < wedges.get(i1 + 1).t0)); IntensityWedge outerwedge = new IntensityWedge(wedges.get(i1).t1, newwedge.GetIntensityW(wedges.get(i1).t1), newwedge.t1, newwedge.e1); wedges.add(i1 + 1, outerwedge); } // split wedge right if (wedges.get(i1).t1 > newwedge.t1) { IntensityWedge leftwedge = new IntensityWedge(wedges.get(i1), newwedge.t1); wedges.add(i1, leftwedge); assert VerifyWedges(); } // displace intermediate wedges for (int i = i0; i <= i1; i++) { IntensityWedge wedge = wedges.get(i); assert ((newwedge.t0 <= wedge.t0) && (wedge.t1 <= newwedge.t1)); wedge.e0 += newwedge.GetIntensityW(wedge.t0); wedge.e1 += newwedge.GetIntensityW(wedge.t1); wedge.slope += newwedge.slope; assert wedge.VerifySlope(); // gap filling wedge if ((i != i0) && (wedges.get(i - 1).t1 < wedges.get(i).t0)) { IntensityWedge gapwedge = new IntensityWedge(wedges.get(i - 1).t1, newwedge.GetIntensityW(wedges.get(i - 1).t1), wedge.t0, newwedge.GetIntensityW(wedge.t0)); gapwedge.slope = newwedge.slope; assert gapwedge.VerifySlope(); wedges.add(i, gapwedge); i++; i1++; } } } ///////////////////////////////////////////// static void Test() { Random ran = new Random(); ran.setSeed(854345); for (int j = 0; j < 20; j++) { IntensityEnvelope ie = new IntensityEnvelope(); for (int i = 0; i < 20; i++) { double t0 = ran.nextDouble(); IntensityWedge wedge = new IntensityWedge(t0, ran.nextDouble() * 2 - 1, t0 + ran.nextDouble(), ran.nextDouble() * 2 - 1); //System.out.println("Wedge: " + wedge); ie.AddWedge(wedge, ran.nextDouble()); } } } ///////////////////////////////////////////// public String toString() { StringBuffer sb = new StringBuffer(); for (int i = 0; i < wedges.size(); i++) sb.append((i == 0 ? "" : " ") + wedges.get(i)); return sb.toString(); } }; ///////////////////////////////////////////// ///////////////////////////////////////////// class TodeNode { OnePathNode opn; DoubleArray spiketimes = new DoubleArray(); List outgoingfibres = new ArrayList(); List incomingfibres = new ArrayList(); boolean bprecodedspikes = false; // allowed to have spikes in the future IntensityEnvelope refactoryenvelope = new IntensityEnvelope(); double nodethreshold = 1.0; double adaptivequotient = 0.0; List incomingsettings = new ArrayList(); double nextspike = -1.0; double externalnodeintensity = 0.0; double refactorynodeintensity = 0.0; double nodeintensity = 0.0; // sum of the above two IntensityEnvelope currentenvelope = new IntensityEnvelope(); ///////////////////////////////////////////// TodeNode(OnePathNode lopn) { opn = lopn; } ///////////////////////////////////////////// void RecalcEnvelope() { currentenvelope.wedges.clear(); for (TodeFibre todefibre : incomingfibres) { for (int i = 0; i < todefibre.fromnode.spiketimes.size(); i++) { for (IntensityWedge wedge : todefibre.intensityenvelope.wedges) currentenvelope.AddWedge(wedge, todefibre.fromnode.spiketimes.get(i) + todefibre.timelength); } } for (int i = 0; i < spiketimes.size(); i++) { for (IntensityWedge wedge : refactoryenvelope.wedges) currentenvelope.AddWedge(wedge, spiketimes.get(i)); } } ///////////////////////////////////////////// void NextSpike(double T) { nextspike = -1.0; for (IntensityWedge wedge : currentenvelope.wedges) { if (wedge.e0 >= nodethreshold) { nextspike = wedge.t0; break; } if (wedge.e1 >= nodethreshold) { double lam = (nodethreshold - wedge.e0) / (wedge.e1 - wedge.e0); nextspike = wedge.t0 * (1.0 - lam) + wedge.t1 * lam; break; } } assert ((nextspike == -1.0) || (nextspike > T)); } } ///////////////////////////////////////////// ///////////////////////////////////////////// class TodeFibre { TodeNode fromnode; TodeNode tonode; double timelength; IntensityEnvelope intensityenvelope = new IntensityEnvelope(); double timelinelengthfac = 1.0; OnePath op; Double[] opseglengths; // for drawing the spike on the path double closestspiketimelength = 0.0; // ///////////////////////////////////////////// TodeFibre(OnePath lop, TodeNode lfromnode, TodeNode ltonode) { op = lop; fromnode = lfromnode; tonode = ltonode; fromnode.outgoingfibres.add(this); tonode.incomingfibres.add(this); // visualization stuff opseglengths = new Double[op.nlines]; for (int i = 0; i < op.nlines; i++) opseglengths[i] = (i == 0 ? 0.0 : opseglengths[i - 1]) + op.MeasureSegmentLength(i); } ///////////////////////////////////////////// void SetPosD(Point2D spos, Point2D stan, double dst) { int j = 0; for ( ; j < opseglengths.length - 1; j++) if (opseglengths[j] >= dst) break; double ljm1 = (j == 0 ? 0.0 : opseglengths[j-1]); double tr = (dst - ljm1) / (opseglengths[j] - ljm1); op.EvalSeg(spos, stan, j, tr); } } ///////////////////////////////////////////// class PosSpikeViz { Point2D spos = new Point2D.Double(); Point2D stan = new Point2D.Double(); } ///////////////////////////////////////////// ///////////////////////////////////////////// class TodeNodeCalc { List todenodes = new ArrayList(); List todefibres = new ArrayList(); double T = 0.0; List todenodesnextspikes = new ArrayList(); IntensityEnvelope iefastattack; IntensityEnvelope iefastsuppress; IntensityEnvelope ieslowsuppress; IntensityEnvelope ieslowattack; IntensityEnvelope iestandardrefactory; double chardisprand[] = null; // some variance in the wordmode distances ///////////////////////////////////////////// void MakeDefaultIntensityEnvelopes() { iefastattack = new IntensityEnvelope(); iefastattack.wedges.add(new IntensityWedge(0.0, 0.0, 0.1, 1.1)); iefastattack.wedges.add(new IntensityWedge(0.1, 1.1, 0.8, 0.0)); iefastattack.Seteextremes(); iefastsuppress = new IntensityEnvelope(); iefastsuppress.wedges.add(new IntensityWedge(0.0, 0.0, 0.1, -1.5)); iefastsuppress.wedges.add(new IntensityWedge(0.1, -1.5, 1.5, -1.4)); iefastsuppress.wedges.add(new IntensityWedge(1.5, -1.4, 2.1, 0.0)); iefastsuppress.Seteextremes(); ieslowsuppress = new IntensityEnvelope(); ieslowsuppress.wedges.add(new IntensityWedge(0.0, 0.0, 0.1, -1.5)); ieslowsuppress.wedges.add(new IntensityWedge(0.1, -1.5, 5.5, -1.4)); ieslowsuppress.wedges.add(new IntensityWedge(5.5, -1.4, 7.1, 0.0)); ieslowsuppress.Seteextremes(); ieslowattack = new IntensityEnvelope(); ieslowattack.wedges.add(new IntensityWedge(0.0, 0.0, 0.5, 1.1)); ieslowattack.wedges.add(new IntensityWedge(0.5, 1.1, 0.8, 0.0)); ieslowattack.Seteextremes(); // back in time slightly to suppress the spike that was there iestandardrefactory = new IntensityEnvelope(); iestandardrefactory.wedges.add(new IntensityWedge(-0.0001, -10.0, 0.9, -5.0)); iestandardrefactory.wedges.add(new IntensityWedge(0.9, -5.0, 1.1, 0.0)); iestandardrefactory.Seteextremes(); chardisprand = new double[26]; Random ran = new Random(); ran.setSeed(1854345); for (int i = 0; i < chardisprand.length; i++) chardisprand[i] = ran.nextDouble(); } ///////////////////////////////////////////// void RecalculateAll() { for (TodeNode todenode : todenodes) { if (!todenode.bprecodedspikes) { while ((todenode.spiketimes.size() != 0) && (todenode.spiketimes.get(todenode.spiketimes.size() - 1) > T)) todenode.spiketimes.pop(); } } for (TodeNode todenode : todenodes) todenode.RecalcEnvelope(); NextSpikeAll(); } ///////////////////////////////////////////// void NextSpikeAll() { todenodesnextspikes.clear(); for (TodeNode todenode : todenodes) { todenode.NextSpike(T); if (todenode.nextspike != -1.0) { if (!todenodesnextspikes.isEmpty() && (todenodesnextspikes.get(0).nextspike > todenode.nextspike)) todenodesnextspikes.clear(); if (todenodesnextspikes.isEmpty() || (todenodesnextspikes.get(0).nextspike == todenode.nextspike)) todenodesnextspikes.add(todenode); } } } ///////////////////////////////////////////// void AdvanceTime(double advance) { double Tnext = T + advance; if (todenodesnextspikes.isEmpty() || (todenodesnextspikes.get(0).nextspike > Tnext)) { T = Tnext; return; } T = todenodesnextspikes.get(0).nextspike; for (TodeNode todenode : todenodesnextspikes) { // set the spike todenode.spiketimes.add(T); // add the intensities which result for (TodeFibre todefibre : todenode.outgoingfibres) { for (IntensityWedge wedge : todefibre.intensityenvelope.wedges) todefibre.tonode.currentenvelope.AddWedge(wedge, T + todefibre.timelength); } for (IntensityWedge wedge : todenode.refactoryenvelope.wedges) todenode.currentenvelope.AddWedge(wedge, T); // how close did any incoming spikes miss this target for (TodeFibre todefibre : todenode.incomingfibres) { todefibre.closestspiketimelength = 0.0; for (int i = 0; i < todefibre.fromnode.spiketimes.size(); i++) { double lclosestspiketimelength = T - (todefibre.fromnode.spiketimes.get(i) + todefibre.timelength + todefibre.intensityenvelope.tpeak); if ((i == 0) || (Math.abs(lclosestspiketimelength) < Math.abs(todefibre.closestspiketimelength))) todefibre.closestspiketimelength = lclosestspiketimelength; } } } //RecalculateAll(); // would redo the partial calculation above NextSpikeAll(); } ///////////////////////////////////////////// TodeNode FindTodeNode(OnePathNode opn) { for (TodeNode tn : todenodes) if (tn.opn == opn) return tn; TodeNode ntn = new TodeNode(opn); todenodes.add(ntn); return ntn; } ///////////////////////////////////////////// void ApplySettingsToNodeFibes(TodeNode todenode, String drawlab) { String[] params = drawlab.split("[\\s,]+"); boolean bwordmode = false; boolean brelative = true; double rwordmodemintime = 0; double rwordmodemaxtime = 0; double rwordmodegap = 0; double llastspiketime = 0.0; try { for (int i = 0; i < params.length; i++) { //System.out.println(i + "::" + params[i]); String param = params[i]; if (bwordmode) { llastspiketime += rwordmodegap; // may need to randomize this todenode.spiketimes.add(llastspiketime); for (int j = 0; j < param.length(); j++) { int iletter = Character.getNumericValue(param.charAt(j)) - Character.getNumericValue('a'); double rletter = (iletter + chardisprand[iletter] * 0.3) / 26.0; double rgap = rwordmodemintime * (1.0 - rletter) + rwordmodemaxtime * rletter; llastspiketime += rgap; todenode.spiketimes.add(llastspiketime); } todenode.bprecodedspikes = true; } else if (param.equals("wordmode")) { i++; rwordmodemintime = Float.parseFloat(params[i]); i++; rwordmodemaxtime = Float.parseFloat(params[i]); i++; rwordmodegap = Float.parseFloat(params[i]); bwordmode = true; } else if (param.equals("threshold")) { i++; todenode.nodethreshold = Float.parseFloat(params[i]); } else if (param.equals("adaptive")) { i++; todenode.adaptivequotient = Float.parseFloat(params[i]); } else if (param.equals("absolute")) { brelative = false; } else if (param.equals("slowattack")) { for (TodeFibre todefibre : todenode.incomingfibres) { if (todefibre.intensityenvelope == iefastattack) todefibre.intensityenvelope = ieslowattack; } } else { double rparam = Float.parseFloat(param); if (brelative) llastspiketime += rparam; else llastspiketime = rparam; todenode.spiketimes.add(llastspiketime); todenode.bprecodedspikes = true; } } } catch (NumberFormatException e) { TN.emitWarning("Error parsing: " + drawlab); } todenode.spiketimes.sort(); } ///////////////////////////////////////////// TodeNodeCalc(List vpaths) { MakeDefaultIntensityEnvelopes(); for (OnePath op : vpaths) { TodeNode tonode = FindTodeNode(op.pnend); if (op.linestyle != SketchLineStyle.SLS_CONNECTIVE) todefibres.add(new TodeFibre(op, FindTodeNode(op.pnstart), tonode)); else if (op.plabedl != null) tonode.incomingsettings.add(op); } // Set default intensity envelopes of incoming fibres by fibre type for (TodeNode todenode : todenodes) { int nposfibres = 0; for (TodeFibre todefibre : todenode.incomingfibres) { if (todefibre.op.linestyle == SketchLineStyle.SLS_WALL) { todefibre.intensityenvelope = ieslowsuppress; todefibre.timelinelengthfac = 0.2; } else { todefibre.intensityenvelope = iefastattack; nposfibres++; } todefibre.timelength = todefibre.op.linelength * todefibre.timelinelengthfac / TN.CENTRELINE_MAGNIFICATION; // linear distance; opseglengths[-1] would be spline length } todenode.nodethreshold = nposfibres + 0.01; todenode.refactoryenvelope = iestandardrefactory; // this could also make use of the order of the incoming connective line with label for (OnePath op : todenode.incomingsettings) ApplySettingsToNodeFibes(todenode, op.plabedl.drawlab); } RecalculateAll(); NextSpikeAll(); } ///////////////////////////////////////////// // this function calculates spikes and intensity independently of the nextspike calculation, and should agree with it List spikelist = new ArrayList(); int nspikelist = 0; int nodeswithintensity = 0; int spikesinfuture = 0; boolean PosSpikes() { nspikelist = 0; nodeswithintensity = 0; spikesinfuture = 0; for (TodeNode todenode : todenodes) { todenode.externalnodeintensity = 0.0; for (TodeFibre todefibre : todenode.incomingfibres) { for (int i = 0; i < todefibre.fromnode.spiketimes.size(); i++) { double st = T - todefibre.fromnode.spiketimes.get(i); if (st < 0.0) { assert todefibre.fromnode.bprecodedspikes; spikesinfuture++; continue; // only can happen for precoded trains } // spike on the fibre if (st < todefibre.timelength) { if (nspikelist == spikelist.size()) spikelist.add(new PosSpikeViz()); PosSpikeViz psv = spikelist.get(nspikelist); double dst = st / todefibre.timelength * todefibre.opseglengths[todefibre.opseglengths.length - 1]; todefibre.SetPosD(psv.spos, psv.stan, dst); nspikelist++; continue; } double est = st - todefibre.timelength; todenode.externalnodeintensity += todefibre.intensityenvelope.GetIntensity(est); } } // add in the refactory intensities from the spikes here todenode.refactorynodeintensity = 0.0; for (int i = 0; i < todenode.spiketimes.size(); i++) { double st = T - todenode.spiketimes.get(i); if (st < 0.0) continue; // only can happen for precoded trains todenode.refactorynodeintensity += todenode.refactoryenvelope.GetIntensity(st); } if ((todenode.externalnodeintensity != 0.0) || (todenode.refactorynodeintensity != 0.0)) nodeswithintensity++; todenode.nodeintensity = todenode.externalnodeintensity + todenode.refactorynodeintensity; } return ((nspikelist != 0) || (nodeswithintensity != 0) || (spikesinfuture != 0)); } } ///////////////////////////////////////////// class TodeNodePanel extends JPanel { SketchDisplay sketchdisplay; JButton buttgeneratetodes = new JButton("Gen Todes"); JTextField tfpathlength = new JTextField("", 5); JButton buttoutputenvelope = new JButton("OutEnv"); JButton buttoutputtrain = new JButton("OutTrain"); JButton buttadvance = new JButton("Advance"); JButton buttadapt = new JButton("Adapt"); JTextField tfadvancetime = new JTextField("5.0", 5); JToggleButton buttanimate = new JToggleButton("Anim"); JTextField tfanimtime = new JTextField("0.02", 5); JLabel labtime = new JLabel("T:"); JTextField tftime = new JTextField(5); Thread animthread = null; boolean bnextfaster = false; int spiralsegspercircuit = 20; int nspirals = 4; GeneralPath[] gpspirals; int nsplayvals = 30; GeneralPath[] gpsplaysnegative; Shape acspike = null; LineStyleAttr lsaspikeout = null; LineStyleAttr lsaspike = null; LineStyleAttr lsanegsplay = null; double prevT = 0.0; TodeNodeCalc tnc; Color lightgreen = new Color(190, 255, 190); ///////////////////////////////////////////// double GetNewLength(OnePath op, double timelinelengthfac, double mu, OnePath nop) { float[] pco = op.GetCoords(); double x0 = pco[0]; double y0 = pco[1]; double x1 = pco[op.nlines * 2]; double y1 = pco[op.nlines * 2 + 1]; double vx = x1 - x0; double vy = y1 - y0; double vlen = Math.sqrt(vx*vx + vy*vy); double xp = x0; double yp = y0; double newleng = 0.0; for (int i = 1; i <= op.nlines; i++) { double xn = pco[i * 2]; double yn = pco[i * 2 + 1]; double xfdot = (vy * (xn - x1) - vx * (yn - y1)) / vlen; xn += vy * xfdot * mu / vlen; yn += -vx * xfdot * mu / vlen; double xpn = xn - xp; double ypn = yn - yp; newleng += Math.sqrt(xpn*xpn + ypn*ypn); if ((nop != null) && (i != op.nlines)) nop.LineTo((float)xn, (float)yn); xp = xn; yp = yn; } return newleng * timelinelengthfac / TN.CENTRELINE_MAGNIFICATION; } ///////////////////////////////////////////// void SetNewLength(TodeFibre todefibre, double targetlength) { double faclo = -0.9; double fachi = 3.0; double newlenglo = GetNewLength(todefibre.op, todefibre.timelinelengthfac, faclo, null); double newlenghi = GetNewLength(todefibre.op, todefibre.timelinelengthfac, fachi, null); if ((targetlength < newlenglo) || (targetlength > newlenghi)) { System.out.println("Target length outside range: " + newlenglo + " " + newlenghi); return; } // the maths are too complex to solve faster than this binary search while (newlenghi - newlenglo > 0.001) { double facmid = (faclo + fachi) / 2; double newlengmid = GetNewLength(todefibre.op, todefibre.timelinelengthfac, facmid, null); if (newlengmid < targetlength) { faclo = facmid; newlenglo = newlengmid; } else { fachi = facmid; newlenghi = newlengmid; } } // now make the path OnePath nop = new OnePath(todefibre.op.pnstart); double newleng = GetNewLength(todefibre.op, todefibre.timelinelengthfac, (faclo + fachi) / 2, nop); nop.EndPath(todefibre.op.pnend); nop.CopyPathAttributes(todefibre.op); List pthstoremove = new ArrayList(); List pthstoadd = new ArrayList(); pthstoremove.add(todefibre.op); pthstoadd.add(nop); sketchdisplay.sketchgraphicspanel.CommitPathChanges(pthstoremove, pthstoadd); sketchdisplay.sketchgraphicspanel.RedrawBackgroundView(); } ///////////////////////////////////////////// void BuildSpirals() { if (SketchLineStyle.strokew == -1.0F) return; double spiralw = SketchLineStyle.strokew * 2.2; gpspirals = new GeneralPath[spiralsegspercircuit * nspirals + 1]; for (int j = 0; j < gpspirals.length; j++) { gpspirals[j] = new GeneralPath(); gpspirals[j].moveTo(0.0F, 0.0F); } for (int i = 1; i < gpspirals.length; i++) { double lam = i * 1.0 / spiralsegspercircuit; // exagerate the spirals on the positive side double x = TN.degsin(lam * 360) * lam * spiralw; double y = -TN.degcos(lam * 360) * lam * spiralw; for (int j = i; j < gpspirals.length; j++) gpspirals[j].lineTo((float)x, (float)y); } acspike = new Ellipse2D.Double(-spiralw * 2.2, -spiralw * 2.2, spiralw * 4.4, spiralw * 4.4); lsaspikeout = new LineStyleAttr(SketchLineStyle.SLS_DETAIL, 2.5F*SketchLineStyle.strokew, 0, 0, 0, Color.white); lsaspike = new LineStyleAttr(SketchLineStyle.SLS_DETAIL, 2.0F*SketchLineStyle.strokew, 0, 0, 0, Color.red); lsanegsplay = new LineStyleAttr(SketchLineStyle.SLS_DETAIL, 0.5F*SketchLineStyle.strokew, 0, 0, 0, Color.yellow); gpsplaysnegative = new GeneralPath[nsplayvals + 1]; double radfull = spiralw * 3.0; double radhalf = spiralw * 1.5; for (int i = 0; i < gpsplaysnegative.length; i++) { double lamrad = (i + 1) * 1.0 / gpsplaysnegative.length; double rad = lamrad * radfull; gpsplaysnegative[i] = new GeneralPath(); for (int j = 0; j < 18; j++) { double vx = TN.degcos(j * 20); double vy = TN.degsin(j * 20); if ((j % 2) == 0) { gpsplaysnegative[i].moveTo(0.0F, 0.0F); gpsplaysnegative[i].lineTo((float)(vx * rad), (float)(vy * rad)); } else if (rad > radhalf) { gpsplaysnegative[i].moveTo((float)(vx * radhalf), (float)(vy * radhalf)); gpsplaysnegative[i].lineTo((float)(vx * rad), (float)(vy * rad)); } } } } ///////////////////////////////////////////// TodeNodePanel(SketchDisplay lsketchdisplay) { sketchdisplay = lsketchdisplay; BuildSpirals(); tftime.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { UpdateT(Float.parseFloat(tftime.getText())); } catch (NumberFormatException ne) {;} sketchdisplay.sketchgraphicspanel.repaint(); }}); buttgeneratetodes.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { GenerateTodes(); } } ); buttoutputenvelope.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { OutputEnvelope(sketchdisplay.sketchgraphicspanel.currgenpath, false); } } ); buttoutputtrain.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { OutputEnvelope(sketchdisplay.sketchgraphicspanel.currgenpath, true); } } ); buttadvance.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { AdvanceEventB(); } } ); buttadapt.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { AdaptPhase(); } } ); buttanimate.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { if (buttanimate.isSelected() && (animthread == null)) { animthread = new Thread(new AdvanceNodeThread()); animthread.start(); } if (!buttanimate.isSelected() && (animthread != null)) animthread.interrupt(); }}); tfadvancetime.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { AdvanceEventB(); } } ); tfpathlength.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { try { double targetlength= Float.parseFloat(tfpathlength.getText()); TodeFibre todefibre = FindTodeFibre(sketchdisplay.sketchgraphicspanel.currgenpath); if (todefibre != null) SetNewLength(todefibre, targetlength); } catch (NumberFormatException e) {;} }}); setLayout(new GridLayout(0, 2)); add(buttgeneratetodes); add(tfpathlength); add(buttadapt); add(new JLabel()); add(buttoutputenvelope); add(buttoutputtrain); add(buttadvance); add(tfadvancetime); add(buttanimate); add(tfanimtime); add(labtime); add(tftime); // IntensityEnvelope.Test(); } ///////////////////////////////////////////// void GenerateTodes() { tnc = null; if (sketchdisplay.sketchgraphicspanel.currgenpath != null) { sketchdisplay.sketchgraphicspanel.SelectConnectedSetsFromSelection(); if (!sketchdisplay.sketchgraphicspanel.vactivepaths.isEmpty()) { tnc = new TodeNodeCalc(sketchdisplay.sketchgraphicspanel.vactivepaths); sketchdisplay.sketchgraphicspanel.ClearSelection(true); sketchdisplay.sketchgraphicspanel.repaint(); } } if (tnc == null) tnc = new TodeNodeCalc(sketchdisplay.sketchgraphicspanel.tsketch.vpaths); tftime.setText(String.format("%.3f", tnc.T)); prevT = -1.0; sketchdisplay.sketchgraphicspanel.repaint(); } ///////////////////////////////////////////// TodeFibre FindTodeFibre(OnePath op) { if ((op == null) || (tnc == null)) return null; for (TodeFibre todefibre : tnc.todefibres) { if (todefibre.op == op) return todefibre; } return null; } ///////////////////////////////////////////// void OutputEnvelope(OnePath op, boolean btrain) { TodeFibre todefibre = FindTodeFibre(op); if (todefibre == null) return; TodeNode todenode = todefibre.fromnode; tfpathlength.setText(String.format("%.3f", todefibre.timelength)); if (btrain) { if (todenode != null) System.out.println("SpikesRel: " + todenode.spiketimes.toStringRel()); return; } if (todefibre != null) { System.out.println("Length: " + todefibre.timelength); System.out.println("IntensityEnvelope: " + todefibre.intensityenvelope); } if (todenode != null) { System.out.println("RefactoryEnvelope: " + todenode.refactoryenvelope); System.out.println("Spikes: " + todenode.spiketimes); System.out.println("SpikesRel: " + todenode.spiketimes.toStringRel()); if (todenode.nextspike != -1.0) System.out.println("Next spike: " + todenode.nextspike); System.out.println("CurrentIntensity: " + todenode.nodeintensity); System.out.println("CurrentEnvelope: "); for (IntensityWedge wedge : todenode.currentenvelope.wedges) System.out.println(" " + wedge); } } ///////////////////////////////////////////// void AdvanceEventB() { bnextfaster = true; if (animthread == null) AdvanceEvent(); } ///////////////////////////////////////////// void AdvanceEvent() { if (tnc == null) return; double advancetime = (!bnextfaster ? 0.02 : 1.0); try { advancetime = Float.parseFloat(!bnextfaster ? tfanimtime.getText() : tfadvancetime.getText()); } catch (NumberFormatException ne) {;} bnextfaster = false; tnc.AdvanceTime(advancetime); tftime.setText(String.format("%.3f", tnc.T)); sketchdisplay.sketchgraphicspanel.repaint(); } ///////////////////////////////////////////// void AdaptPhase() { System.out.println("Adapt"); for (TodeNode todenode : tnc.todenodes) { if (todenode.adaptivequotient != 0.0) { System.out.println("Adaptive " + todenode.adaptivequotient); for (TodeFibre todefibre : todenode.incomingfibres) System.out.println(todefibre.closestspiketimelength); } } } ///////////////////////////////////////////// void UpdateT(double lT) { if (lT < tnc.T) { tnc.T = lT; tnc.RecalculateAll(); } else { while (lT > tnc.T) tnc.AdvanceTime(lT - tnc.T); } tftime.setText(String.format("%.3f", tnc.T)); sketchdisplay.sketchgraphicspanel.repaint(); } ///////////////////////////////////////////// class AdvanceNodeThread implements Runnable { ///////////////////////////////////////////// public void run() { try { while (true) { AdvanceEvent(); Thread.sleep(50); } } catch (InterruptedException ie) {;} animthread = null; } } ///////////////////////////////////////////// // 1 - 1 / (1 + x) int asymd(double val, double valsca, int len) { double kap = 1.0 - 1.0 / (1.0 + Math.abs(val / valsca)); int res = (int)(kap * (len - 1) + 0.9); assert ((res >= 0) && (res < len)); return res; } ///////////////////////////////////////////// void painttodenode(GraphicsAbstraction ga) { if (tnc == null) return; boolean bsomeaction = tnc.PosSpikes(); if (!bsomeaction && buttanimate.isSelected()) buttanimate.setSelected(false); // draw the spirals on the nodes AffineTransform at = ga.g2d.getTransform(); for (TodeNode todenode : tnc.todenodes) { if (todenode.nodeintensity == 0.0) continue; ga.g2d.translate(todenode.opn.pn.getX(), todenode.opn.pn.getY()); // draw any positive external node intensity if ((todenode.externalnodeintensity > 0.0) && (todenode.externalnodeintensity > todenode.nodeintensity)) { int nivalue = asymd(todenode.externalnodeintensity, todenode.nodethreshold, gpspirals.length); GeneralPath gppos = gpspirals[nivalue]; ga.drawShape(gppos, SketchLineStyle.activepnlinestyleattr, lightgreen); } // draw any positive node intensity if (todenode.nodeintensity > 0.0) { int nivalue = asymd(todenode.nodeintensity, todenode.nodethreshold, gpspirals.length); GeneralPath gppos = gpspirals[nivalue]; ga.drawShape(gppos, SketchLineStyle.activepnlinestyleattr, Color.green); } // draw any negative external node intensity if (todenode.externalnodeintensity < 0.0) { int nivalue = asymd(-todenode.externalnodeintensity, todenode.nodethreshold, gpspirals.length); GeneralPath gppos = gpspirals[nivalue]; ga.drawShape(gppos, SketchLineStyle.activepnlinestyleattr, Color.red); } // draw any negative negative refactory splay if ((todenode.nodeintensity < 0.0) && (todenode.refactorynodeintensity < 0.0)) { int nivalue = (int)(gpsplaysnegative.length * Math.abs(todenode.refactorynodeintensity / (todenode.refactoryenvelope.emin + 0.01)) + 0.9); GeneralPath gppos = gpsplaysnegative[Math.min(nivalue, gpsplaysnegative.length - 1)]; ga.drawShape(gppos, lsanegsplay); } ga.g2d.setTransform(at); } // draw the spikes on the fibres for (int i = 0; i < tnc.nspikelist; i++) { PosSpikeViz psv = tnc.spikelist.get(i); double spikel = SketchLineStyle.strokew * 2.2 / psv.stan.distance(0.0, 0.0); Line2D lnspike = new Line2D.Double(psv.spos.getX(), psv.spos.getY(), psv.spos.getX() - psv.stan.getX() * spikel, psv.spos.getY() - psv.stan.getY() * spikel); ga.drawShape(lnspike, lsaspikeout); ga.drawShape(lnspike, lsaspike); } // highlight the nodes spiked since last paint for (TodeNode todenode : tnc.todenodes) { if (todenode.spiketimes.size() == 0) continue; double tspike = todenode.spiketimes.get(todenode.spiketimes.size() - 1); if ((tspike > prevT) && (tspike <= tnc.T)) { ga.g2d.translate(todenode.opn.pn.getX(), todenode.opn.pn.getY()); ga.g2d.setColor(Color.yellow); ga.g2d.fill(acspike); ga.g2d.setTransform(at); } } prevT = tnc.T; } } tunnelx-20140102.orig/src/OnePathNode.java0000644000000000000000000004136211762432750015102 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.Graphics2D; import java.awt.geom.Line2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.geom.GeneralPath; import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.AffineTransform; import java.io.IOException; import java.awt.BasicStroke; import java.awt.Shape; import java.util.List; import java.util.ArrayList; import java.util.Collections; // // // OnePathNode // // // this is going to implement Comparable containing the function compareTo() ///////////////////////////////////////////// class OnePathNode implements Comparable { Point2D.Float pn = null; // the altitude of this node (inherited into areas so we can draw them in order). // also a value that's saved into the xml file when IsCentrelineNode() float zalt = 0.0F; private Shape pnell = null; // for drawing. float currstrokew = -1.0F; // used for lazy evaluation to make the shapes int nclosenodesbefore = 0; // number of nodes close (within strokewidth distance) of this node when we added it in. int pathcount = 0; // number of paths which link to this node. int pathcountch; // spare variable for checking the pathcount static String strConnectiveNode = "__CONNECTIVE NODE__"; // used to overload value of pnstationlabel String shortstationlabel = null; // calculated when needed and cached String pnstationlabel = null; // lifted from the centreline legs, and used to tell if this is a centreline node OnePath opconn = null; // connection to a single path which we can circle around, and will match the pathcount RefPathO ropconn = null; int icnodevisiblesubset = 0; double proxdist = -1.0F; // value set by other weighting operations for previewing float icollam = 0.0F; ///////////////////////////////////////////// String ShortStationLabel() { if (shortstationlabel != null) return shortstationlabel; // recursively strip off leading values that are all the same shortstationlabel = pnstationlabel; int ileaddot = -1; while (true) { int idot = pnstationlabel.indexOf(".", ileaddot + 1); if (idot == -1) break; String leadingv = pnstationlabel.substring(0, idot + 1); int imatches = 0; int imissmatches = 0; // find the subsets this node could be in RefPathO sref = new RefPathO(ropconn); do { assert sref.ToNode() == this; if (sref.FromNode().IsCentrelineNode()) { String ostationlabel = sref.FromNode().pnstationlabel; if ((idot + 1 < ostationlabel.length()) && leadingv.equals(ostationlabel.substring(0, idot + 1))) imatches++; else imissmatches++; } } while (!sref.AdvanceRoundToNode(ropconn)); if ((imissmatches != 0) || (imatches == 0)) break; ileaddot = idot; shortstationlabel = pnstationlabel.substring(ileaddot + 1); } return shortstationlabel; } ///////////////////////////////////////////// // used for sorting a list; not making a map public int compareTo(OnePathNode opn) { if (pn.x != opn.pn.x) return (pn.x < opn.pn.x ? -1 : 1); if (pn.y != opn.pn.y) return (pn.y < opn.pn.y ? -1 : 1); //assert false; //if (this != opn) //System.out.println(" using compareTo in OPN on " + hashCode() + "," + opn.hashCode()); assert ((this == opn) || (hashCode() != opn.hashCode())); return hashCode() - opn.hashCode(); // also consider the numbering given when coming in from the XML file. } // may need also to implement the equals. ///////////////////////////////////////////// boolean IsCentrelineNode() { return ((pnstationlabel != null) && (pnstationlabel != strConnectiveNode)); } ///////////////////////////////////////////// boolean IsZSetNode() { return ((pnstationlabel != null) && (pnstationlabel != null)); } ///////////////////////////////////////////// void DumpNodeInfo(LineOutputStream los, String sten, Vec3 sketchLocOffset) throws IOException { los.WriteLine(sten + ": " + (pnstationlabel == null ? "" : (pnstationlabel == strConnectiveNode ? "RelConnNode" : "Centrelinenode=" + pnstationlabel)) + " z=" + (zalt + sketchLocOffset.z) + " pathcount=" + pathcount + " pathcountch=" + pathcountch); } ///////////////////////////////////////////// // can be used for running through the array again. void SetNodeCloseBefore(List vnodes, int n) { // count how many nodes are within strokewidth of this node nclosenodesbefore = 0; currstrokew = -1.0F; for (int i = 0; i < n; i++) { OnePathNode opn = vnodes.get(i); assert opn != this; if ((Math.abs(pn.getX() - opn.pn.getX()) < SketchLineStyle.strokew) && (Math.abs(pn.getY() - opn.pn.getY()) < SketchLineStyle.strokew)) nclosenodesbefore++; } } ///////////////////////////////////////////// // how to deal with connections via a zdiff setting? OnePathNode ConnectingCentrelineNode() { if (IsCentrelineNode()) return this; // find the subsets this node could be in OnePathNode res = null; RefPathO sref = new RefPathO(ropconn); do { assert sref.ToNode() == this; if (sref.FromNode().IsCentrelineNode()) { if (res != null) TN.emitMessage("We connect to two centreline nodes (will have to select closest by path length later)"); res = sref.FromNode(); } } while (!sref.AdvanceRoundToNode(ropconn)); return res; } ///////////////////////////////////////////// // this is lazy evaluation, since we can change the stroke and then reload an old sketch. Shape Getpnell() { if (currstrokew != SketchLineStyle.strokew) { currstrokew = SketchLineStyle.strokew; if (nclosenodesbefore == 0) pnell = new Rectangle2D.Float((float)pn.getX() - 2 * currstrokew, (float)pn.getY() - 2 * currstrokew, 4 * currstrokew, 4 * currstrokew); // these are other shapes to discriminate else { GeneralPath gpnell = new GeneralPath(); float rad = currstrokew * (nclosenodesbefore + 5) / 2.0F; int nnodes = (nclosenodesbefore + 8) / 2; boolean balternating = ((nclosenodesbefore > 2) && ((nclosenodesbefore % 2) == 1)); gpnell.moveTo((float)pn.getX(), (float)pn.getY() - (balternating ? -rad : rad)); for (int i = 1; i < nclosenodesbefore + 3; i++) { float lrad = (balternating && ((i % 2) == 1) ? rad * 0.2F : rad); double thet = Math.PI * 2.0 * i / (nclosenodesbefore + 3); gpnell.lineTo((float)(pn.getX() + lrad * Math.sin(thet)), (float)(pn.getY() - (balternating ? -lrad : lrad) * Math.cos(thet))); } gpnell.closePath(); pnell = gpnell; } } return pnell; } ///////////////////////////////////////////// OnePathNode(float x, float y, float z) { pn = new Point2D.Float(x, y); zalt = z; pathcount = 0; } ///////////////////////////////////////////// // this is where we track round boolean CheckPathCount() { pathcountch = 0; OnePath op = opconn; assert ((this == op.pnend) || (this == op.pnstart)); boolean bFore = (op.pnend == this); float ptang = op.GetTangent(!bFore); boolean btangcrossx = false; do { pathcountch++; assert pathcountch <= pathcount; if (!bFore) { bFore = op.baptlfore; op = op.aptailleft; } else { bFore = op.bapfrfore; op = op.apforeright; } assert ((!bFore ? op.pnstart : op.pnend) == this); float tang = op.GetTangent(!bFore); // we're allowed one crossing of the x-axis for wrap-around if (tang < ptang) { assert !btangcrossx; btangcrossx = true; } ptang = tang; } while (!((op == opconn) && (bFore == (op.pnend == this)))); assert pathcountch == pathcount; return true; } ///////////////////////////////////////////// OnePath GetDropDownConnPath() { OnePath op = opconn; boolean bFore = (op.pnend == this); do { if (op.IsDropdownConnective() && (op.pnstart == this)) return op; if (!bFore) { bFore = op.baptlfore; op = op.aptailleft; } else { bFore = op.bapfrfore; op = op.apforeright; } } while (!((op == opconn) && (bFore == (op.pnend == this)))); // make a new one OnePath opddconn = new OnePath(this); opddconn.LineTo((float)pn.getX(), (float)pn.getY()); opddconn.EndPath(null); opddconn.linestyle = SketchLineStyle.SLS_CONNECTIVE; opddconn.plabedl = new PathLabelDecode(); opddconn.plabedl.barea_pres_signal = SketchLineStyle.ASE_HCOINCIDE; // bit of a useless way of looking up which value indexes it. for (opddconn.plabedl.iarea_pres_signal = 0; opddconn.plabedl.iarea_pres_signal < SketchLineStyle.nareasignames; opddconn.plabedl.iarea_pres_signal++) if (SketchLineStyle.areasigeffect[opddconn.plabedl.iarea_pres_signal] == opddconn.plabedl.barea_pres_signal) break; System.out.println("AreaPresSig " + opddconn.plabedl.iarea_pres_signal + " " + opddconn.plabedl.barea_pres_signal); assert opddconn.pnend.pathcount == 0; assert opddconn.IsDropdownConnective(); return opddconn; } ///////////////////////////////////////////// // if we have equality, a dropdown connective path may have been fused. // it will be happy if we can get the pitch boundary and the dropped invisible boundary the right way round void InsertOnNode(OnePath op, boolean bFore) { assert (bFore ? op.pnend : op.pnstart) == this; if (op.bpathvisiblesubset) icnodevisiblesubset++; // single path connecting to empty node here if (pathcount == 0) { assert opconn == null; opconn = op; ropconn = new RefPathO(op, bFore); assert ropconn.ToNode() == this; if (!bFore) { assert op.aptailleft == null; op.aptailleft = op; op.baptlfore = false; } else { assert op.apforeright == null; op.apforeright = op; op.bapfrfore = true; } pathcount = 1; return; } float tang = op.GetTangent(!bFore); // find a place to insert boolean lbFore = (opconn.pnend == this); if (opconn.pnend == opconn.pnstart) // avoid the null pointer { if ((!lbFore ? opconn.aptailleft : opconn.apforeright) == null) lbFore = !lbFore; } boolean pbFore = lbFore; OnePath pop = opconn; boolean nbFore; OnePath nop; float ptang = pop.GetTangent(!pbFore); boolean bsomech = false; // protect against all edges coinciding while (true) { // find the next point along if (!pbFore) { nbFore = pop.baptlfore; nop = pop.aptailleft; } else { nbFore = pop.bapfrfore; nop = pop.apforeright; } assert ((!nbFore ? nop.pnstart : nop.pnend) == this); float ntang = nop.GetTangent(!nbFore); // we're allowed one crossing of the x-axis for wrap-around if (ptang < ntang) { bsomech = true; if ((ptang <= tang) && (tang <= ntang)) break; } else if (ptang > ntang) { bsomech = true; if ((ptang <= tang) || (tang <= ntang)) break; } // this detects final pair if it is equal (and all are) else { if (!bsomech && ((nop == opconn) && (nbFore == lbFore))) break; } pbFore = nbFore; pop = nop; ptang = ntang; assert (!((pop == opconn) && (pbFore == lbFore))); } // link the path we're inserting in if (!bFore) { assert op.aptailleft == null; op.aptailleft = nop; op.baptlfore = nbFore; } else { assert op.apforeright == null; op.apforeright = nop; op.bapfrfore = nbFore; } // link the right hand path into this path if (!pbFore) { assert pop.aptailleft == nop; assert pop.baptlfore == nbFore; pop.aptailleft = op; pop.baptlfore = bFore; } else { assert pop.apforeright == nop; assert pop.bapfrfore == nbFore; pop.apforeright = op; pop.bapfrfore = bFore; } pathcount++; opconn = op; ropconn.op = op; ropconn.bFore = bFore; assert ropconn.ToNode() == this; } ///////////////////////////////////////////// RefPathO srefpathconn = new RefPathO(); RefPathO prefpathconn = new RefPathO(); boolean RemoveOnNode(RefPathO rop) { assert rop.ToNode() == this; if (rop.op.bpathvisiblesubset) icnodevisiblesubset--; // single path connecting to single node here if (pathcount == 1) { assert ropconn.cequals(rop); assert opconn == rop.op; if (!ropconn.bFore) { assert ropconn.op.aptailleft == ropconn.op; ropconn.op.aptailleft = null; } else { assert ropconn.op.apforeright == ropconn.op; ropconn.op.apforeright = null; } ropconn.op = null; opconn = null; pathcount = 0; return true; } // use this to find previous prefpathconn.ccopy(ropconn); srefpathconn.ccopy(ropconn); while (!srefpathconn.AdvanceRoundToNode(rop)) { assert srefpathconn.ToNode() == this; prefpathconn.ccopy(srefpathconn); assert !srefpathconn.cequals(ropconn); } srefpathconn.AdvanceRoundToNode(rop); // delink the path we're inserting in if (!rop.bFore) { assert rop.op.aptailleft == srefpathconn.op; rop.op.aptailleft = null; } else { assert rop.op.apforeright == srefpathconn.op; rop.op.apforeright = null; } // relink the right hand path into the left path if (!prefpathconn.bFore) { assert prefpathconn.op.aptailleft == rop.op; assert prefpathconn.op.baptlfore == rop.bFore; prefpathconn.op.aptailleft = srefpathconn.op; prefpathconn.op.baptlfore = srefpathconn.bFore; } else { assert prefpathconn.op.apforeright == rop.op; assert prefpathconn.op.bapfrfore == rop.bFore; prefpathconn.op.apforeright = srefpathconn.op; prefpathconn.op.bapfrfore = srefpathconn.bFore; } // decrement and quit pathcount--; opconn = prefpathconn.op; ropconn.ccopy(prefpathconn); assert ropconn.ToNode() == this; assert !ropconn.cequals(rop); return false; } ///////////////////////////////////////////// static boolean CheckAllPathCounts(List vnodes, List vpaths) { for (OnePathNode opn : vnodes) opn.pathcountch = 0; for (OnePath op : vpaths) { op.pnstart.pathcountch++; op.pnend.pathcountch++; } int tccn = 0; for (OnePathNode opn : vnodes) { assert opn.pathcountch == opn.pathcount; tccn += opn.pathcount; assert opn.CheckPathCount(); } assert tccn == 2 * vpaths.size(); // proves all are in the list. return true; } ///////////////////////////////////////////// ///////////////////////////////////////////// /* class sortpathnodes implements Comparator { public int compare(OnePathNode opn1, OnePathNode opn2) { if (opn1.pn.getX() != opn2.pn.getX()) return (opn1.pn.getX() < opn2.pn.getX() ? -1 : 1); if (opn1.pn.getY() != opn2.pn.getY()) return (opn1.pn.getY() < opn2.pn.getY() ? -1 : 1); // something with the Z value and the pnstationlabel known stuff return 0; } } ///////////////////////////////////////////// class sortendpathnodes implements Comparator { public int compare(RefPathO opn1, RefPathO opn2) { // do the endpoints x and y business // something with the Z value and the pnstationlabel known stuff return 0; } } ///////////////////////////////////////////// static void VerifyLoadedPathNodes(List vnodes, List lvpaths) { List lrefnodes = new ArrayList(); for (OnePath op : lvpaths) { lrefnodes.add(new RefPathO(op, true)); lrefnodes.add(new RefPathO(op, false)); } Collections.sort(lrefnodes, new sortendpathnodes()); // might need to sort the main vnodes list to help identification. // when we do identify all the nodes, they all start with pathcount == 0, and this increases as we call addpath // Some thought needs doing to handle the endpoints; when the z-value is set; when there is a name; when there needs to be an id to resolve inconsistencies; etc. // } */ } tunnelx-20140102.orig/src/SketchGrid.java0000644000000000000000000001261111762432750014760 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2005 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.geom.Point2D; import java.awt.geom.Line2D; import java.awt.geom.AffineTransform; import java.awt.geom.GeneralPath; import java.awt.Graphics2D; import java.awt.geom.NoninvertibleTransformException; import java.awt.Dimension; ///////////////////////////////////////////// class SketchGrid { float xorig = 0.0F; float yorig = 0.0F; float[] gridspacing = new float[20]; int[] gridlineslimit = new int[20]; int ngridspacing = 0; // the sizes of the above dynamic arrays int igridspacing = 0; // the chosen index of the grid spacing float gridspace = 1.0F; // a temporary copy of the grid origin which can be set and reset float txorig = 0.0F; float tyorig = 0.0F; // the region the lines are drawn in float xlo, xhi, ylo, yhi; int ixlo, ixhi, iylo, iyhi; // the index positions of the lines GeneralPath gpgrid = new GeneralPath(); ///////////////////////////////////////////// SketchGrid(float lxorig, float lyorig) { xorig = lxorig; txorig = lxorig; yorig = lyorig; tyorig = lyorig; } ///////////////////////////////////////////// public void SetGridSpacing(int gsoffset) { float mwid = Math.max(xhi - xlo, yhi - ylo); int ligridspacing; for (ligridspacing = 0; ligridspacing < ngridspacing; ligridspacing++) { float lgridspace = gridspacing[ligridspacing] * TN.CENTRELINE_MAGNIFICATION; if (mwid / lgridspace < gridlineslimit[ligridspacing]) break; } // set the values incl the offset igridspacing = Math.max(0, Math.min(ngridspacing - 1, ligridspacing + gsoffset)); gridspace = gridspacing[igridspacing] * TN.CENTRELINE_MAGNIFICATION; assert gridspace != 0.0; // set the index positions // xlo < ixlo * gridspace + xorig ixlo = (int)Math.floor((xlo - txorig) / gridspace) + 1; ixhi = (int)Math.floor((xhi - txorig) / gridspace); iylo = (int)Math.floor((ylo - tyorig) / gridspace) + 1; iyhi = (int)Math.floor((yhi - tyorig) / gridspace); if (igridspacing == gridlineslimit.length - 1) { int gridlinelimit = gridlineslimit[igridspacing]; int xdi = ((ixhi - ixlo) - gridlinelimit) / 2; if (xdi > 0) { ixlo += xdi; ixhi -= xdi; } int ydi = ((iyhi - iylo) - gridlinelimit) / 2; if (ydi > 0) { iylo += ydi; iyhi -= ydi; } } } ///////////////////////////////////////////// public void GenerateMetreGrid() { gpgrid.reset(); for (int i = ixlo; i <= ixhi; i++) { gpgrid.moveTo(i * gridspace + txorig, ylo); gpgrid.lineTo(i * gridspace + txorig, yhi); } for (int i = iylo; i <= iyhi; i++) { gpgrid.moveTo(xlo, i * gridspace + tyorig); gpgrid.lineTo(xhi, i * gridspace + tyorig); } } ///////////////////////////////////////////// boolean ClosestGridPoint(Point2D res, double ptx, double pty, double scale) { int ix = (int)Math.floor((ptx - txorig) / gridspace + 0.5F); int iy = (int)Math.floor((pty - tyorig) / gridspace + 0.5F); if ((ix < ixlo) || (ix > ixhi) || (iy < iylo) || (iy > iyhi)) return false; res.setLocation(ix * gridspace + txorig, iy * gridspace + tyorig); double md = Math.max(Math.abs(res.getX() - ptx), Math.abs(res.getY() - pty)); return ((scale == -1.0) || (md < scale)); } ///////////////////////////////////////////// Point2D.Float gridscrcorner = new Point2D.Float(); Point2D.Float scrcorner = new Point2D.Float(); void SetUntransRanges(float tx, float ty, AffineTransform currtrans, boolean bfirst) throws NoninvertibleTransformException { scrcorner.setLocation(tx, ty); currtrans.inverseTransform(scrcorner, gridscrcorner); float x = (float)gridscrcorner.getX(); float y = (float)gridscrcorner.getY(); if (bfirst || (x < xlo)) xlo = x; if (bfirst || (x > xhi)) xhi = x; if (bfirst || (y < ylo)) ylo = y; if (bfirst || (y > yhi)) yhi = y; } ///////////////////////////////////////////// void UpdateGridCoords(Dimension csize, AffineTransform currtrans, boolean bhasrotation, SketchBackgroundPanel backgroundpanel) { try { SetUntransRanges(0.0F, 0.0F, currtrans, true); SetUntransRanges(csize.width, csize.height, currtrans, false); if (bhasrotation) { SetUntransRanges(csize.width, 0.0F, currtrans, false); SetUntransRanges(0.0F, csize.height, currtrans, false); } } catch (NoninvertibleTransformException ex) {;} int pigridspacing = igridspacing; SetGridSpacing(backgroundpanel.gsoffset); if (pigridspacing != igridspacing) backgroundpanel.tfgridspacing.setText(String.valueOf(gridspacing[igridspacing])); GenerateMetreGrid(); } }; tunnelx-20140102.orig/src/SketchLineStyle.java0000644000000000000000000011766212261213471016007 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import javax.swing.JComboBox; import javax.swing.JPanel; import javax.swing.JButton; import java.awt.BorderLayout; import java.awt.GridLayout; import javax.swing.JCheckBox; import javax.swing.JToggleButton; import javax.swing.JTextField; import javax.swing.JTabbedPane; import javax.swing.JComponent; import java.awt.Insets; //import java.lang.NumberFormatException; import java.awt.CardLayout; import java.awt.Dimension; import java.awt.Component; import javax.swing.border.Border; import javax.swing.BorderFactory; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemListener; import java.awt.event.ItemEvent; import java.awt.event.KeyEvent; import java.awt.event.FocusEvent; import java.awt.event.FocusAdapter; import java.awt.event.FocusListener; import java.awt.BasicStroke; import java.awt.Font; import java.awt.Color; import java.io.IOException; import javax.swing.Action; import javax.swing.JLabel; import javax.swing.AbstractAction; import javax.swing.KeyStroke; import javax.swing.JCheckBoxMenuItem; import java.util.List; import java.util.ArrayList; import java.util.Map; import java.util.TreeMap; import java.util.Collections; import java.util.Collection; import java.util.Comparator; import javax.swing.event.DocumentListener; import javax.swing.event.DocumentEvent; import javax.swing.text.BadLocationException; // // // SketchLineStyle // // ///////////////////////////////////////////// // to finish make sort all edges so the colours are in order when they're plotted by height class pathcollamzcomp implements Comparator { public int compare(OnePath op1, OnePath op2) { float op1z = (op1.pnstart.icollam + op1.pnend.icollam) / 2; float op2z = (op2.pnstart.icollam + op2.pnend.icollam) / 2; if (op1z < op2z) return -1; if (op1z > op2z) return 1; return 0; } } ///////////////////////////////////////////// class SketchLineStyle extends JPanel { // parallel arrays of wall style info. static String[] linestylenames = { "Centreline", "Wall", "Est. Wall", "Pitch Bound", "Ceiling Bound", "Detail", "Invisible", "Connective", "Filled" }; static String[] shortlinestylenames = { "Cent", "Wall", "EstW", "Pitc", "CeilB", "Detl", "Invs", "Conn", "Fill" }; static final int SLS_CENTRELINE = 0; static final int SLS_WALL = 1; static final int SLS_ESTWALL = 2; static final int SLS_PITCHBOUND = 3; static final int SLS_CEILINGBOUND = 4; static final int SLS_DETAIL = 5; static final int SLS_INVISIBLE = 6; static final int SLS_CONNECTIVE = 7; static final int SLS_FILLED = 8; static final int SLS_SYMBOLOUTLINE = 9; // not a selected style. static float strokew = -1.0F; static Color fontcol = new Color(0.7F, 0.3F, 1.0F); static LabelFontAttr stationPropertyFontAttr = null; static Font defaultfontlab = null; // area-connective type signals which get loaded and their numeric values (should really be a map between ints) static final int ASE_KEEPAREA = 0; // default state static final int ASE_VERYSTEEP = 0; // not used yet, but will define an area that's a foreshortened pitch wall static final int ASE_HCOINCIDE = 1; // pitch dropdown connection (on paths, not areas) static final int ASE_OUTLINEAREA = 2; // pitch hole static final int ASE_KILLAREA = 3; // column static final int ASE_ZSETRELATIVE = 5; // setting relative z displacement between the nodes (on paths, not areas) static final int ASE_ELEVATIONPATH = 6; // defines the connective as forming the path of an elevation diagramette static final int ASE_OUTERAREA = 7; // assigned to an outer area of the diagram (not selectable) static final int ASE_NOAREA = 8; // assigned to the object when path is part of a tree (not selectable) static final int ASE_SKETCHFRAME = 55; // defining the interior of a frame static String[] areasignames = new String[12]; static int[] areasigeffect = new int[12]; static int iareasigelev = -1; static int iareasigframe = -1; static int nareasignames = 0; //Colours for drawing symbols private static Color linestylesymbcol = new Color(0.0F, 0.1F, 0.8F); private static Color linestylesymbcolinvalid = new Color(0.3F, 0.3F, 0.6F, 0.77F); //Line style used as a border for printing to help it to be cut out static LineStyleAttr printcutoutlinestyleattr = null; //Line styles for drawing paths when not in detail mode static Color linestylecolactive = Color.magenta; static Color linestylecolactiveCen = Color.magenta.brighter(); static LineStyleAttr[] ActiveLineStyleAttrs = new LineStyleAttr[10]; static LineStyleAttr[] ActiveLineStyleAttrsConnective = new LineStyleAttr[10]; static float mouperplinlength; static LineStyleAttr[] inSelSubsetLineStyleAttrs = new LineStyleAttr[10]; static LineStyleAttr[] inSelSubsetLineStyleAttrsConnective = new LineStyleAttr[10]; static Color notInSelSubsetCol = new Color(0.6F, 0.6F, 0.9F); static Color blankbackimagecol = new Color(0.9F, 0.9F, 0.6F); static LineStyleAttr[] notInSelSubsetLineStyleAttrs = new LineStyleAttr[10]; static LineStyleAttr framebackgrounddragstyleattr = null; //Line styles for drawing nodes static LineStyleAttr pnlinestyleattr = null; static LineStyleAttr activepnlinestyleattr = null; static LineStyleAttr firstselpnlinestyleattr = null; static LineStyleAttr lastselpnlinestyleattr = null; static LineStyleAttr middleselpnlinestyleattr = null; //Lines for drawing symbols to screen static LineStyleAttr linestylesymb = null; static LineStyleAttr linestylefirstsymb = null; static LineStyleAttr linestylesymbinvalid = null; static LineStyleAttr linestylefirstsymbinvalid = null; static LineStyleAttr lineactivestylesymb = null; static LineStyleAttr fillstylesymb = null; static LineStyleAttr fillstylefirstsymb = null; static LineStyleAttr fillstylesymbinvalid = null; static LineStyleAttr fillstylefirstsymbinvalid = null; static LineStyleAttr fillactivestylesymb = null; //Lines for hatching areas static LineStyleAttr linestylehatch1 = null; static LineStyleAttr linestylehatch2 = null; static String[] linestylebuttonnames = { "", "W", "E", "P", "C", "D", "I", "N", "F" }; static int[] linestylekeystrokes = { 0, KeyEvent.VK_W, KeyEvent.VK_E, KeyEvent.VK_P, KeyEvent.VK_C, KeyEvent.VK_D, KeyEvent.VK_I, KeyEvent.VK_N, KeyEvent.VK_F }; //These should be removed eventually... static BasicStroke gridStroke = null; static Color gridColor = null; // used to get back for defaults and to the active path. SketchDisplay sketchdisplay; // (we must prevent the centreline style from being selected -- it's special). JComboBox linestylesel = new JComboBox(linestylenames); JToggleButton pthsplined = new JToggleButton("s"); // tabbing panes that are put in the bottom part CardLayout pthstylecardlayout = new CardLayout(); JPanel pthstylecards = new JPanel(pthstylecardlayout); String pthstylecardlayoutshown = null; // a panel displayed when no path is selected (useful for holding a few spare buttons) JPanel pthstylenonconn = new JPanel(); // panel of deselect and delete buttons JPanel pathcoms = new JPanel(new GridLayout(1, 0)); // the other panel types ConnectiveCentrelineTabPane pthstylecentreline = new ConnectiveCentrelineTabPane(); ConnectiveLabelTabPane pthstylelabeltab = new ConnectiveLabelTabPane(); ConnectiveAreaSigTabPane pthstyleareasigtab; SymbolsDisplay symbolsdisplay; // a tabbed pane // secondary sets of colours which over-ride using the icolindex attribute in lines // static for convenient access from OnePath.paintW static boolean bDepthColours = false; static boolean bPathSubsetColours = false; static Color[] linestylecolsindex = new Color[100]; static Color[] areastylecolsindex = new Color[200]; static float zlo; static float zhi; ///////////////////////////////////////////// static Color GetColourFromCollam(float icollam, boolean bAreas) { Color[] stylecolsindex = (bAreas ? areastylecolsindex : linestylecolsindex); int i = (int)(icollam * stylecolsindex.length); int i0 = Math.max(0, Math.min(stylecolsindex.length - 1, i)); return stylecolsindex[i0]; } ///////////////////////////////////////////// // this will be a list Map subsetattrstylesmap = new TreeMap(); boolean bsubsetattributesneedupdating = false; SubsetAttrStyle GetSubsetAttrStyle(String sasname) // dead func { // find the upper default we inherit from if (sasname == null) return null; return subsetattrstylesmap.get(sasname); } ///////////////////////////////////////////// static void SetIColsByZ(List vpaths, Collection tsvpathsviz, List vnodes, Collection vsareas) { // extract the zrange from what we see zlo = 0.0F; zhi = 0.0F; // scan through using the half-points of each vector boolean bfirst = true; for (OnePath op : tsvpathsviz) { float z = (op.pnstart.zalt + op.pnend.zalt) / 2; if (bfirst || (z < zlo)) zlo = z; if (bfirst || (z > zlo)) zhi = z; bfirst = false; } // the setting of the zalts is done from a menu auto command TN.emitMessage("zrange in view zlo " + zlo + " zhi " + zhi); // now set the zalts on all the paths for (OnePathNode opn : vnodes) opn.icollam = (opn.zalt - zlo) / (zhi - zlo); // sort the edges by height so lower ones don't over-write upper ones Collections.sort(vpaths, new pathcollamzcomp()); // now set the zalts on all the areas for (OneSArea osa : vsareas) osa.icollam = (osa.zalt - zlo) / (zhi - zlo); bDepthColours = true; bPathSubsetColours = false; } ///////////////////////////////////////////// static void SetIColsProximity(int style, OneSketch tsketch, OnePathNode ops) { if (ops == null) return; // heavyweight stuff ProximityDerivation pd = new ProximityDerivation(tsketch); pd.ShortestPathsToCentrelineNodes(ops, null, null); double dlo = 0.0; double dhi = pd.distmax; if (style == 1) { dlo = pd.distmincnode; dhi = pd.distmaxcnode; } // separate out case if (dlo == dhi) dhi += dlo * 0.00001; // fill in the colours at the end-nodes for (OnePathNode opn : tsketch.vnodes) { double dp = opn.proxdist; opn.icollam = (float)((dp - dlo) / (dhi - dlo)); if (style == 0) opn.icollam = 1.0F - opn.icollam; // make red 0.0 else if (style == 1) { if (dp <= dlo) opn.icollam = 1.0F; else opn.icollam = (float)((dlo * dlo) / (dp * dp)); } } bDepthColours = true; bPathSubsetColours = false; } ///////////////////////////////////////////// public class AclsButt extends AbstractAction { int index; public AclsButt(int lindex) { super(linestylebuttonnames[lindex]); index = lindex; putValue(SHORT_DESCRIPTION, linestylenames[index]); putValue(MNEMONIC_KEY, new Integer(linestylekeystrokes[index])); } public void actionPerformed(ActionEvent e) { linestylesel.setSelectedIndex(index); } } ///////////////////////////////////////////// class LineStyleButton extends JButton { int index; LineStyleButton(int lindex) { super(new AclsButt(lindex)); index = lindex; setMargin(new Insets(1, 1, 1, 1)); } }; ///////////////////////////////////////////// static Color ColorBlueMagenta = new Color(0.7F, 0.0F, 1.0F); static Color ColorDarkGreen = new Color(0.0F, 0.9F, 0.0F); static Color ColorGreenYellow = new Color(0.5F, 0.8F, 0.0F); static Color ColorYellowGreen = new Color(0.7F, 0.7F, 0.0F); ///////////////////////////////////////////// static void SetStrokeWidths(float lstrokew, boolean bnotdotted) { strokew = lstrokew; //TN.emitMessage("New stroke width: " + strokew); //Set Grid stroke and colour gridStroke = new BasicStroke(1.0F * strokew); gridColor = Color.black; //Set Line style attributes for the cut out line when printing printcutoutlinestyleattr = new LineStyleAttr(SLS_SYMBOLOUTLINE, 3.0F * strokew, 6 * 2, 4 * 2, 0, Color.lightGray); //Set Line style attributes for non active path nodes pnlinestyleattr = new LineStyleAttr(SLS_DETAIL, 1.0F * strokew, 0, 0, 0, Color.blue); //Set Line style attributes for active path nodes activepnlinestyleattr = new LineStyleAttr(SLS_DETAIL, 1.0F * strokew, 0, 0, 0, Color.magenta); //Set Line style attributes for the first selected path nodes firstselpnlinestyleattr = new LineStyleAttr(SLS_DETAIL, 1.0F * strokew, 0, 0, 0, new Color(1.0F, 0.5F, 1.0F)); //Set Line style attributes for the last selected path nodes lastselpnlinestyleattr = new LineStyleAttr(SLS_DETAIL, 1.0F * strokew, 0, 0, 0, new Color(0.8F, 0.0F, 0.8F)); //Set Line style attributes for the middle selected path nodes middleselpnlinestyleattr = new LineStyleAttr(SLS_DETAIL, 1.0F * strokew, 0, 0, 0, Color.magenta); //Set Line style attributes for hatching areas linestylehatch1 = new LineStyleAttr(SLS_DETAIL, 1.0F * strokew, 0, 0, 0, Color.blue); linestylehatch2 = new LineStyleAttr(SLS_DETAIL, 1.0F * strokew, 0, 0, 0, Color.cyan); //Set default font stationPropertyFontAttr = new LabelFontAttr(fontcol, new Font("Serif", 0, Math.max(4, (int)(strokew * 15)))); //Lines for drawing symbols to screen linestylesymb = new LineStyleAttr(SLS_DETAIL, 1.0F*strokew, 0, 0, 0, linestylesymbcol); linestylesymbinvalid = new LineStyleAttr(SLS_DETAIL, 1.0F*strokew, 0, 0, 0, linestylesymbcolinvalid); lineactivestylesymb = new LineStyleAttr(SLS_DETAIL, 1.0F*strokew, 0, 0, 0, linestylecolactive); fillstylesymb = new LineStyleAttr(SLS_FILLED, 0.0F*strokew, 0, 0, 0, linestylesymbcol); fillstylesymbinvalid = new LineStyleAttr(SLS_FILLED, 0.0F*strokew, 0, 0, 0, linestylesymbcolinvalid); fillactivestylesymb = new LineStyleAttr(SLS_FILLED, 0.0F*strokew, 0, 0, 0, linestylecolactive); // set 'in selected subsets' line style attributes //LineStyleAttr(int llinestyle, float lstrokewidth, float lspikegap, float lgapleng, float lspikeheight, Color lstrokecolour) float strokewd = (bnotdotted ? 0.0F : strokew); inSelSubsetLineStyleAttrs[SLS_CENTRELINE] = new LineStyleAttr(SLS_CENTRELINE, 0.5F*strokew, 0, 0, 0, Color.red); inSelSubsetLineStyleAttrs[SLS_WALL] = new LineStyleAttr(SLS_WALL, 2.0F*strokew, 0, 0, 0, Color.blue); inSelSubsetLineStyleAttrs[SLS_ESTWALL] = new LineStyleAttr(SLS_ESTWALL, 2.0F*strokew, 12*strokewd, 6*strokewd, 0, Color.blue); inSelSubsetLineStyleAttrs[SLS_PITCHBOUND] = new LineStyleAttr(SLS_PITCHBOUND, 1.0F*strokew, 16*strokewd, 6*strokewd, 0, ColorBlueMagenta); inSelSubsetLineStyleAttrs[SLS_CEILINGBOUND] = new LineStyleAttr(SLS_CEILINGBOUND, 1.0F*strokew, 16*strokewd, 6*strokewd, 0, Color.cyan); inSelSubsetLineStyleAttrs[SLS_DETAIL] = new LineStyleAttr(SLS_DETAIL, 1.0F*strokew, 0, 0, 0, Color.blue); inSelSubsetLineStyleAttrs[SLS_INVISIBLE] = new LineStyleAttr(SLS_INVISIBLE, 1.0F*strokew, 0, 0, 0, ColorDarkGreen); inSelSubsetLineStyleAttrs[SLS_CONNECTIVE] = new LineStyleAttr(SLS_CONNECTIVE, 1.0F*strokew, 6*strokewd, 3*strokewd, 0, ColorGreenYellow); inSelSubsetLineStyleAttrs[SLS_FILLED] = new LineStyleAttr(SLS_FILLED, 0.0F*strokew, 0, 0, 0, Color.black); // symbol paint background. inSelSubsetLineStyleAttrs[SLS_SYMBOLOUTLINE] =new LineStyleAttr(SLS_SYMBOLOUTLINE,3.0F*strokew, 0, 0, 0, Color.black);// for printing. // connective line variations inSelSubsetLineStyleAttrsConnective[SketchLineStyle.ASE_ELEVATIONPATH] = new LineStyleAttr(SLS_CONNECTIVE, 0.75F*strokew,4*strokewd, 3*strokewd, 0, ColorYellowGreen); // set 'active (highlighted)' line style attributes ActiveLineStyleAttrs[SLS_CENTRELINE] = new LineStyleAttr(SLS_CENTRELINE, 0.5F*strokew, 0, 0, 0, linestylecolactiveCen); ActiveLineStyleAttrs[SLS_WALL] = new LineStyleAttr(SLS_WALL, 2.0F*strokew, 0, 0, 0, linestylecolactive); ActiveLineStyleAttrs[SLS_ESTWALL] = new LineStyleAttr(SLS_ESTWALL, 2.0F*strokew, 12*strokewd, 6*strokewd, 0, linestylecolactive); ActiveLineStyleAttrs[SLS_PITCHBOUND] = new LineStyleAttr(SLS_PITCHBOUND, 1.0F*strokew, 16*strokewd, 6*strokewd, 0, linestylecolactive); ActiveLineStyleAttrs[SLS_CEILINGBOUND] = new LineStyleAttr(SLS_CEILINGBOUND, 1.0F*strokew, 16*strokewd, 6*strokewd, 0, linestylecolactive); // experimental to see if pitch bounds can draw automatically on the selected edge ActiveLineStyleAttrs[SLS_DETAIL] = new LineStyleAttr(SLS_DETAIL, 1.0F*strokew, 0, 0, 0, linestylecolactive); ActiveLineStyleAttrs[SLS_INVISIBLE] = new LineStyleAttr(SLS_INVISIBLE, 1.0F*strokew, 0, 0, 0, linestylecolactive); ActiveLineStyleAttrs[SLS_CONNECTIVE] = new LineStyleAttr(SLS_CONNECTIVE, 1.0F*strokew, 6*strokewd, 3*strokewd, 0, linestylecolactive); ActiveLineStyleAttrs[SLS_FILLED] = new LineStyleAttr(SLS_FILLED, 0.0F*strokew, 0, 0, 0, linestylecolactive); // symbol paint background. ActiveLineStyleAttrs[SLS_SYMBOLOUTLINE] = new LineStyleAttr(SLS_SYMBOLOUTLINE, 3.0F * strokew, 0, 0, 0, Color.white);// for printing. // connective line variations ActiveLineStyleAttrsConnective[SketchLineStyle.ASE_ELEVATIONPATH] = new LineStyleAttr(SLS_CONNECTIVE, 1.0F*strokew, 4*strokewd, 3*strokewd, 0, linestylecolactive); mouperplinlength = 8*strokew; // set 'not in selected subsets' line style attributes notInSelSubsetLineStyleAttrs[SLS_CENTRELINE] = new LineStyleAttr(SLS_CENTRELINE, 0.5F*strokew, 0, 0, 0, notInSelSubsetCol); notInSelSubsetLineStyleAttrs[SLS_WALL] = new LineStyleAttr(SLS_WALL, 2.0F*strokew, 0, 0, 0, notInSelSubsetCol); notInSelSubsetLineStyleAttrs[SLS_ESTWALL] = new LineStyleAttr(SLS_ESTWALL, 2.0F*strokew, 12*strokewd, 6*strokewd, 0, notInSelSubsetCol); notInSelSubsetLineStyleAttrs[SLS_PITCHBOUND] = new LineStyleAttr(SLS_PITCHBOUND, 1.0F*strokew, 16*strokewd, 6*strokewd, 0, notInSelSubsetCol); notInSelSubsetLineStyleAttrs[SLS_CEILINGBOUND]=new LineStyleAttr(SLS_CEILINGBOUND,1.0F*strokew, 16*strokewd, 6*strokewd, 0, notInSelSubsetCol); notInSelSubsetLineStyleAttrs[SLS_DETAIL] = new LineStyleAttr(SLS_DETAIL, 1.0F*strokew, 0, 0, 0, notInSelSubsetCol); notInSelSubsetLineStyleAttrs[SLS_INVISIBLE] = new LineStyleAttr(SLS_INVISIBLE, 1.0F*strokew, 0, 0, 0, notInSelSubsetCol); notInSelSubsetLineStyleAttrs[SLS_CONNECTIVE] = new LineStyleAttr(SLS_CONNECTIVE, 1.0F*strokew, 6*strokewd, 3*strokewd, 0, notInSelSubsetCol); notInSelSubsetLineStyleAttrs[SLS_FILLED] = new LineStyleAttr(SLS_FILLED, 0.0F*strokew, 0, 0, 0, notInSelSubsetCol); // symbol paint background. notInSelSubsetLineStyleAttrs[SLS_SYMBOLOUTLINE] = new LineStyleAttr(SLS_SYMBOLOUTLINE,3.0F*strokew,0, 0, 0, notInSelSubsetCol);// for printing. //Set Line style attributes for selected image carrying connective path framebackgrounddragstyleattr = new LineStyleAttr(SLS_DETAIL, 2.0F * strokew, 0, 0, 0, new Color(0.87F, 0.4F, 0.1F)); } // this is dangerous but seems to work. boolean bsettingaction = false; ///////////////////////////////////////////// // we don't otherwise have a way to recover which card is visible void Showpthstylecard(String lpthstylecardlayoutshown) { pthstylecardlayoutshown = lpthstylecardlayoutshown; pthstylecardlayout.show(pthstylecards, pthstylecardlayoutshown); } ///////////////////////////////////////////// void SetClearedTabs(String tstring, boolean benableconnbuttons) { sketchdisplay.SetEnabledConnectiveSubtype(benableconnbuttons); Showpthstylecard(tstring); // zero the other visual areas pthstylelabeltab.labtextfield.setText(""); pthstylelabeltab.setTextPosCoords(-1, -1); pthstylelabeltab.jcbarrowpresent.setSelected(false); pthstylelabeltab.jcbboxpresent.setSelected(false); LSpecSymbol(true, null); //?? if (!FileAbstraction.bIsApplet) // can't handle this { if (pthstyleareasigtab.areasignals.getItemCount() != 0) pthstyleareasigtab.areasignals.setSelectedIndex(0); pthstyleareasigtab.SetFrameSketchInfoText(null); } } ///////////////////////////////////////////// boolean SetFrameZSetRelative(OnePath op) { float pnodeconnzsetrelative = op.plabedl.nodeconnzsetrelative; try { op.plabedl.nodeconnzsetrelative = Float.parseFloat(pthstyleareasigtab.tfsubmapping.getText().trim()); } catch (NumberFormatException e) { System.out.println(pthstyleareasigtab.tfsubmapping.getText()); }; return (pnodeconnzsetrelative != op.plabedl.nodeconnzsetrelative); } ///////////////////////////////////////////// // this has got two uses; when we select a new path, // or we change the linestyle of a path boolean SetConnectiveParametersIntoBoxes(OnePath op) { if (op == null) { bsettingaction = true; SetClearedTabs("Nonconn", false); bsettingaction = false; return false; } bsettingaction = true; op.linestyle = linestylesel.getSelectedIndex(); // this would recopy it just after it had been copied over, I guess if (op.linestyle == SLS_CONNECTIVE) { // symbols present in this one if ((op.plabedl != null) && !op.plabedl.vlabsymb.isEmpty()) { Showpthstylecard("Symbol"); symbolsdisplay.SelEnableButtons(op.subsetattr); symbolsdisplay.UpdateSymbList(op.plabedl.vlabsymb, op.subsetattr); } // label type at this one else if ((op.plabedl != null) && !op.plabedl.sfontcode.equals("")) { pthstylelabeltab.fontstyles.setSelectedIndex(pthstylelabeltab.lfontstyles.indexOf(op.plabedl.sfontcode)); pthstylelabeltab.setTextPosCoords(op.plabedl.fnodeposxrel, op.plabedl.fnodeposyrel); pthstylelabeltab.jcbarrowpresent.setSelected(op.plabedl.barrowpresent); pthstylelabeltab.jcbboxpresent.setSelected(op.plabedl.bboxpresent); String ldrawlab = op.plabedl.drawlab; if (!ldrawlab.equals(pthstylelabeltab.labtextfield.getText())) { pthstylelabeltab.labtextfield.setText(ldrawlab); pthstylelabeltab.labtextfield.setCaretPosition(0); System.out.println("Setting cpos "+ldrawlab.length()); } Showpthstylecard("Label"); pthstylelabeltab.labtextfield.requestFocus(); } // area-signal present at this one else if ((op.plabedl != null) && (op.plabedl.iarea_pres_signal != 0)) { pthstyleareasigtab.areasignals.setSelectedIndex(op.plabedl.iarea_pres_signal); pthstyleareasigtab.SetFrameSketchInfoText(op); Showpthstylecard("Area-Sig"); } // none specified; free choice else SetClearedTabs("Conn", true); } else if (op.linestyle == SLS_CENTRELINE) { pthstylecentreline.tfhead.setText(((op.plabedl != null) && (op.plabedl.centrelinehead != null)) ? op.plabedl.centrelinehead : "--nothing--"); pthstylecentreline.tftail.setText(((op.plabedl != null) && (op.plabedl.centrelinetail != null)) ? op.plabedl.centrelinetail : "--nothing--"); pthstylecentreline.tfelev.setText(((op.plabedl != null) && (op.plabedl.centrelineelev != null)) ? op.plabedl.centrelineelev : ""); Showpthstylecard("Centreline"); } else { sketchdisplay.SetEnabledConnectiveSubtype(false); Showpthstylecard("Nonconn"); } bsettingaction = false; return true; } ///////////////////////////////////////////// // we have some confounding situations of what to show when there is no path shown void SetParametersIntoBoxes(OnePath op) { bsettingaction = true; if (op != null) { bsettingaction = true; pthsplined.setSelected(op.bWantSplined); linestylesel.setSelectedIndex(op.linestyle); } // null case else { if (linestylesel.getSelectedIndex() == SLS_CENTRELINE) linestylesel.setSelectedIndex(SLS_DETAIL); // set the splining by default. // except make the splining off if the type is connective, which we don't really want splined since it's distracting. // pthsplined.setSelected(sketchdisplay.miDefaultSplines.isSelected() && (linestylesel.getSelectedIndex() != SLS_CONNECTIVE)); bsettingaction = false; sketchdisplay.SetEnabledConnectiveSubtype(false); Showpthstylecard("Nonconn"); } bsettingaction = false; // we have a connective type, so should load the contents here SetConnectiveParametersIntoBoxes(op); } ///////////////////////////////////////////// void GoSetParametersCurrPath() // this calls function below { OnePath op = sketchdisplay.sketchgraphicspanel.currgenpath; if ((op == null) || !sketchdisplay.sketchgraphicspanel.bEditable) return; // if the spline changes then the area should change too. if (SetParametersFromBoxes(op)) { sketchdisplay.sketchgraphicspanel.RedrawBackgroundView(); sketchdisplay.sketchgraphicspanel.SketchChanged(SketchGraphics.SC_CHANGE_STRUCTURE); } } ///////////////////////////////////////////// // returns true if anything actually changed. boolean SetParametersFromBoxes(OnePath op) { boolean bRes = false; int llinestyle = linestylesel.getSelectedIndex(); if (op.linestyle != llinestyle) bRes = true; op.linestyle = llinestyle; if (op.bWantSplined != pthsplined.isSelected()) bRes = true; op.bWantSplined = pthsplined.isSelected(); // go and spline it if required // (should do this in the redraw actually). if ((op.pnend != null) && (op.bWantSplined != op.bSplined)) op.Spline(op.bWantSplined && !OnePath.bHideSplines, false); // we have a connective type, so should load the contents here if (op.plabedl != null) { // symbols are loaded as they are pressed. //if ((op.plabedl != null) && !op.plabedl.vlabsymb.isEmpty()) // pthstylecardlayout.show(pthstylecards, "Symbol"); // label type at this one if (pthstylecardlayoutshown.equals("Label")) { String ldrawlab = pthstylelabeltab.labtextfield.getText().trim(); int lifontcode = pthstylelabeltab.fontstyles.getSelectedIndex(); String lsfontcode = (lifontcode == -1 ? "default" : pthstylelabeltab.lfontstyles.get(lifontcode)); assert op.plabedl.drawlab != null; assert op.plabedl.sfontcode != null; if (!op.plabedl.drawlab.equals(ldrawlab) || !op.plabedl.sfontcode.equals(lsfontcode)) { // no redraw if the text was changed on a survey type (so no redraw) if (!op.plabedl.sfontcode.equals(lsfontcode)) bRes = true; else if (lsfontcode.equals("survey")) ; else if (!op.plabedl.drawlab.equals(ldrawlab)) bRes = true; op.plabedl.drawlab = ldrawlab; op.plabedl.sfontcode = lsfontcode; } float pfnodeposxrel = op.plabedl.fnodeposxrel; float pfnodeposyrel = op.plabedl.fnodeposyrel; boolean pbarrowpresent = op.plabedl.barrowpresent; boolean pbboxpresent = op.plabedl.bboxpresent; try { op.plabedl.fnodeposxrel = Float.parseFloat(pthstylelabeltab.tfxrel.getText()); op.plabedl.fnodeposyrel = Float.parseFloat(pthstylelabeltab.tfyrel.getText()); } catch (NumberFormatException e) { TN.emitWarning(pthstylelabeltab.tfxrel.getText() + "/" + pthstylelabeltab.tfyrel.getText()); }; op.plabedl.barrowpresent = pthstylelabeltab.jcbarrowpresent.isSelected(); op.plabedl.bboxpresent = pthstylelabeltab.jcbboxpresent.isSelected(); if ((pfnodeposxrel != op.plabedl.fnodeposxrel) || (pfnodeposyrel != op.plabedl.fnodeposyrel) || (pbarrowpresent != op.plabedl.barrowpresent) || (pbboxpresent != op.plabedl.bboxpresent)) bRes = true; } else { if (!op.plabedl.drawlab.equals("") || !op.plabedl.sfontcode.equals("")) bRes = true; op.plabedl.drawlab = ""; op.plabedl.sfontcode = ""; } // area-signal present at this one (no need to specialize because default is number 0) // if (pthstylecardlayoutshown.equals("Area-sig")) int liarea_pres_signal = pthstyleareasigtab.areasignals.getSelectedIndex(); if ((liarea_pres_signal != -1) && (op.plabedl.iarea_pres_signal != liarea_pres_signal)) { op.plabedl.iarea_pres_signal = liarea_pres_signal; // look up in combobox int bareapre = op.plabedl.barea_pres_signal; op.plabedl.barea_pres_signal = areasigeffect[op.plabedl.iarea_pres_signal]; // change in state. update pthstyleareasigtab.SetFrameSketchInfoText(op); bRes = true; } if (op.plabedl.barea_pres_signal == SketchLineStyle.ASE_ZSETRELATIVE) { if (SetFrameZSetRelative(op)) bRes = true; } } op.SetSubsetAttrs(sketchdisplay.subsetpanel.sascurrent, sketchdisplay.sketchlinestyle.pthstyleareasigtab.sketchframedefCopied); // font change return bRes; } ///////////////////////////////////////////// void SetConnTabPane(String tstring) { OnePath op = sketchdisplay.sketchgraphicspanel.currgenpath; if ((op == null) || !sketchdisplay.sketchgraphicspanel.bEditable) { TN.emitWarning("Must have connective path selected"); // maybe use disabled buttons return; } Showpthstylecard(tstring); if (op.plabedl == null) op.plabedl = new PathLabelDecode(); if (tstring.equals("Label")) { // new paths are not survey type int lifontcode = pthstylelabeltab.fontstyles.getSelectedIndex(); String lsfontcode = (lifontcode == -1 ? "default" : pthstylelabeltab.lfontstyles.get(lifontcode)); if (lsfontcode.equals("survey")) pthstylelabeltab.fontstyles.setSelectedIndex(pthstylelabeltab.lfontstyles.indexOf("default")); pthstylelabeltab.labtextfield.requestFocus(); } else if (tstring.equals("Symbol")) symbolsdisplay.SelEnableButtons(op.subsetattr); } ///////////////////////////////////////////// class DocAUpdate implements DocumentListener, ActionListener { public void changedUpdate(DocumentEvent e) { //TN.emitMessage("EEECU: " + e.toString()); } public void removeUpdate(DocumentEvent e) { if (!bsettingaction) { // TN.emitMessage("EEEd: " + e.getOffset() + " " + e.getLength()); if (e.getOffset() == 0) // update when entire thing disappears (which includes up to first character); the document has already been changed so we can't recover what was deleted GoSetParametersCurrPath(); } } public void insertUpdate(DocumentEvent e) { //TN.emitMessage("EEEi: " + e.getOffset() + " " + e.getLength()); if (!bsettingaction) { // update when space is pressed try { String istr = e.getDocument().getText(e.getOffset(), e.getLength()); if ((istr.indexOf(' ') != -1) || (istr.indexOf('\n') != -1) || (istr.indexOf('%') != -1)) GoSetParametersCurrPath(); } catch (BadLocationException ex) {;}; } } public void actionPerformed(ActionEvent e) { if (!bsettingaction) { GoSetParametersCurrPath(); sketchdisplay.sketchgraphicspanel.ObserveSelection(sketchdisplay.sketchgraphicspanel.currgenpath, null, 10); } } }; ///////////////////////////////////////////// class DocActionUpdate implements ActionListener { int iy; // to help track where the events are coming from DocActionUpdate(int liy) { iy = liy; } public void actionPerformed(ActionEvent e) { if (!bsettingaction) { GoSetParametersCurrPath(); sketchdisplay.sketchgraphicspanel.ObserveSelection(sketchdisplay.sketchgraphicspanel.currgenpath, null, 11); //System.out.println("EEEAP: " + iy + " " + bsettingaction); } } }; ///////////////////////////////////////////// // from when the symbol buttons are pressed boolean LSpecSymbol(boolean bOverwrite, String name) { // shares much code from GoSetParametersCurrPath OnePath op = sketchdisplay.sketchgraphicspanel.currgenpath; if ((op == null) || !sketchdisplay.sketchgraphicspanel.bEditable) return false; if ((op.linestyle != SLS_CONNECTIVE) || (op.plabedl == null)) return false; assert ((name != null) || bOverwrite); if ((name == null) && op.plabedl.vlabsymb.isEmpty()) return false; // no change if (bOverwrite) op.plabedl.vlabsymb.clear(); if (name != null) op.plabedl.vlabsymb.add(name); symbolsdisplay.UpdateSymbList(op.plabedl.vlabsymb, op.subsetattr); sketchdisplay.sketchgraphicspanel.SketchChanged(SketchGraphics.SC_CHANGE_SYMBOLS); op.GenerateSymbolsFromPath(); sketchdisplay.sketchgraphicspanel.RedrawBackgroundView(); return true; } ///////////////////////////////////////////// void SetupSymbolStyleAttr() { // apply a setup on all the symbols in the attribute styles for (SubsetAttrStyle sas : subsetattrstylesmap.values()) { for (SubsetAttr sa : sas.msubsets.values()) { for (SymbolStyleAttr ssa : sa.subautsymbolsmap.values()) ssa.SetUp(sketchdisplay.mainbox.vgsymbolstsketches); } } } ///////////////////////////////////////////// SketchLineStyle(SymbolsDisplay lsymbolsdisplay, SketchDisplay lsketchdisplay) { symbolsdisplay = lsymbolsdisplay; sketchdisplay = lsketchdisplay; pthstyleareasigtab = new ConnectiveAreaSigTabPane(this); setBackground(TN.sketchlinestyle_col); Border bord_loweredbevel = BorderFactory.createLoweredBevelBorder(); Border bord_redline = BorderFactory.createLineBorder(Color.blue); Border bord_compound = BorderFactory.createCompoundBorder(bord_redline, bord_loweredbevel); pthstylecards.setBorder(bord_compound); // do the button panel JPanel buttpanel = new JPanel(); buttpanel.setLayout(new GridLayout(1, 0)); for (int i = 0; i < linestylebuttonnames.length; i++) { if (!linestylebuttonnames[i].equals("")) buttpanel.add(new LineStyleButton(i)); } pthsplined.setMargin(new Insets(1, 1, 1, 1)); buttpanel.add(pthsplined); linestylesel.setSelectedIndex(SLS_DETAIL); // the listener for all events among the linestyles DocAUpdate docaupdate = new DocAUpdate(); // action listeners on the linestyles pthsplined.addActionListener(new DocActionUpdate(1)); // change of linestyle linestylesel.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { if (!bsettingaction) { if (sketchdisplay.miDefaultSplines.isSelected()) pthsplined.setSelected((linestylesel.getSelectedIndex() != SLS_CONNECTIVE) && (linestylesel.getSelectedIndex() != SLS_CENTRELINE)); GoSetParametersCurrPath(); SetConnectiveParametersIntoBoxes(sketchdisplay.sketchgraphicspanel.currgenpath); } } } ); // LSpecSymbol calls added with the symbolsdisplay // put in the tabbing panes updates pthstyleareasigtab.areasignals.addActionListener(new DocActionUpdate(2)); pthstylelabeltab.fontstyles.addActionListener(new DocActionUpdate(3333)); pthstylelabeltab.tfxrel.addActionListener(new DocActionUpdate(4)); pthstylelabeltab.tfyrel.addActionListener(new DocActionUpdate(5)); pthstylelabeltab.jcbarrowpresent.addActionListener(new DocActionUpdate(6)); pthstylelabeltab.jcbboxpresent.addActionListener(new DocActionUpdate(7)); pthstylelabeltab.labtextfield.getDocument().addDocumentListener(docaupdate); pthstyleareasigtab.tfsubmapping.getDocument().addDocumentListener(docaupdate); // cancel buttons pthstyleareasigtab.jbcancel.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { SetClearedTabs("Nonconn", true); GoSetParametersCurrPath(); } } ); pthstylelabeltab.jbcancel.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { SetClearedTabs("Nonconn", true); GoSetParametersCurrPath(); } } ); symbolsdisplay.jbcancel.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { SetClearedTabs("Nonconn", true); GoSetParametersCurrPath(); } } ); // the clear symbols button symbolsdisplay.jbclear.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { LSpecSymbol(true, null); } } ); pthstylecards.add(pthstylenonconn, "Nonconn"); // when no connected path is selected pthstylecards.add(pthstylecentreline, "Centreline"); // this should have buttons that take you to the other four types pthstylecards.add(pthstylelabeltab, "Label"); pthstylecards.add(symbolsdisplay, "Symbol"); pthstylecards.add(pthstyleareasigtab, "Area-Sig"); // do the layout of the main thing. JPanel partpanel = new JPanel(new GridLayout(3, 1)); partpanel.add(linestylesel); partpanel.add(buttpanel); partpanel.add(pathcoms); // delete and deselect setLayout(new BorderLayout()); add(partpanel, BorderLayout.NORTH); add(pthstylecards, BorderLayout.CENTER); // fill in the colour rainbow for showing weighting and depth for (int i = 0; i < linestylecolsindex.length; i++) { float a = (float)i / linestylecolsindex.length ; linestylecolsindex[i] = new Color(Color.HSBtoRGB(0.5F + 1.2F * a, 1.0F, 0.9F)); //linestylecolsindex[i] = new Color(a, (1.0F - a) * 0.2F, 1.0F - a); } for (int i = 0; i < areastylecolsindex.length; i++) { float a = (float)i / areastylecolsindex.length ; //linestylecolsindex[i] = new Color(); // fcolw = new Color(0.8F, 1.0F, 1.0F, 0.6F); //areastylecolsindex[i] = new Color(0.7F + a * 0.3F, 1.0F - a * 0.3F, 1.0F, 0.6F); int col = Color.HSBtoRGB(0.6F * (1.0F - a) + 0.06F, 1.0F, 1.0F) + 0x61000000; areastylecolsindex[i] = new Color(col, true); //linestylecolsindex[i] = new Color(Color.HSBtoRGB(0.9F * a, 1.0F, 0.9F)); } } ///////////////////////////////////////////// Color GetDepthColourPoint(float x, float y, float z) { float a = (z - zlo) / (zhi - zlo); int icolindex = Math.max(Math.min((int)(a * areastylecolsindex.length), areastylecolsindex.length - 1), 0); return areastylecolsindex[icolindex]; } ///////////////////////////////////////////// SubsetAttrStyle GetSubsetSelection(String lstylename) // dead func { for (SubsetAttrStyle sas : subsetattrstylesmap.values()) { if (lstylename.equals(sas.stylename)) return sas; } TN.emitWarning("Not found subsetstylename " + lstylename); return null; } ///////////////////////////////////////////// // this gets called on opening, and whenever a set of sketches which contains some fontcolours gets loaded void UpdateSymbols(boolean bfirsttime) { assert bsubsetattributesneedupdating; // update the underlying symbols for (OneSketch tsketch : sketchdisplay.mainbox.vgsymbolstsketches) { assert tsketch.bsketchfileloaded; tsketch.MakeAutoAreas(); } // fill in all the attributes for (SubsetAttrStyle sas : subsetattrstylesmap.values()) sas.FillAllMissingAttributes(); // push the newly loaded stuff into the panels SetupSymbolStyleAttr(); pthstyleareasigtab.UpdateAreaSignals(areasignames, nareasignames); // extract out and sort List lsaslist = new ArrayList(); for (SubsetAttrStyle lsas : subsetattrstylesmap.values()) { if (lsas.bselectable) lsaslist.add(lsas); } Collections.sort(lsaslist); int iprevselindex = sketchdisplay.subsetpanel.jcbsubsetstyles.getSelectedIndex(); sketchdisplay.subsetpanel.jcbsubsetstyles.removeAllItems(); for (SubsetAttrStyle lsas : lsaslist) sketchdisplay.subsetpanel.jcbsubsetstyles.addItem(lsas); bsubsetattributesneedupdating = false; if ((iprevselindex != -1) && (iprevselindex < sketchdisplay.subsetpanel.jcbsubsetstyles.getItemCount())) sketchdisplay.subsetpanel.jcbsubsetstyles.setSelectedIndex(iprevselindex); } }; tunnelx-20140102.orig/src/ProximityDerivation.java0000644000000000000000000003676312261213471016770 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2004 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.geom.Line2D; import java.awt.geom.GeneralPath; import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.ArrayList; import java.util.Set; import java.util.HashSet; import java.util.PriorityQueue; ///////////////////////////////////////////// class parainstance implements Comparable { double sdist; double zdisp; OnePathNode opn; ///////////////////////////////////////////// parainstance(double lsdist, double lzdisp, OnePathNode lopn) { sdist = lsdist; zdisp = lzdisp; opn = lopn; } ///////////////////////////////////////////// public int compareTo(parainstance pi) { double ll = sdist - pi.sdist; return (ll < 0.0 ? -1 : (ll > 0.0 ? 1 : 0)); } } ///////////////////////////////////////////// class Parainstancequeue { PriorityQueue prioqueue = new PriorityQueue(); List proxdistsetlist = new ArrayList(); // list of nodes that have been visited so their proxdists can be reset // may be able to replace proxdistsetlist with a map from OnePathNode to Double, so can get rid of the proxdist // these settings determine which types of the path are traversed // the requirements differ when we are morphing or setting the z values boolean bDropdownConnectiveTraversed = true; boolean bCentrelineTraversed = true; // when false, would we also want to abolish linking through centreline nodes as well? boolean bAreasTraversed = true; // tries to link across areas with a straight line to the nodes in the area double fcenlinelengthfactor = 10.0; // factor of length added to centreline connections (to deal with vertical line cases) boolean bhcoincideLinesActive; ///////////////////////////////////////////// RefPathO Dsrefpathconn = new RefPathO(); void AddNode(OnePathNode opn, double dist, double zdisp) { opn.proxdist = dist; proxdistsetlist.add(opn); if (bAreasTraversed) { Dsrefpathconn.ccopy(opn.ropconn); do { AddNodeAreaCrossings(Dsrefpathconn, opn, dist, zdisp); } while (!Dsrefpathconn.AdvanceRoundToNode(opn.ropconn)); } Dsrefpathconn.ccopy(opn.ropconn); do { AddNodePathsConnections(Dsrefpathconn, opn, dist, zdisp); } while (!Dsrefpathconn.AdvanceRoundToNode(opn.ropconn)); } void AddNodeAreaCrossings(RefPathO srefpathconn, OnePathNode opn, double dist, double zdisp) { OnePath op = srefpathconn.op; if (op.linestyle == SketchLineStyle.SLS_CENTRELINE) return; if (op.linestyle == SketchLineStyle.SLS_CONNECTIVE) return; OneSArea osa = (srefpathconn.bFore ? op.karight : op.kaleft); if (osa == null) return; GeneralPath gpconnline = new GeneralPath(); for (RefPathO rpo : osa.refpaths) { OnePathNode opo = (rpo.bFore ? rpo.op.pnend : rpo.op.pnstart); if (opo.proxdist != -1.0) continue; // gpconnline.clear(); // gpconnline.moveTo(opn.pn.getX(), opn.pn.getY()); // gpconnline.lineTo(opo.pn.getX(), opo.pn.getY()); // gpconnline.subtract(osa.aarea); // System.out.println(" "+connlin.isEmpty()); // if (gpconnline.isEmpty()) { double vx = opo.pn.getX() - opn.pn.getX(); double vy = opo.pn.getY() - opn.pn.getY(); double addd = Math.sqrt(vx*vx + vy*vy); prioqueue.offer(new parainstance(dist + addd, zdisp, opo)); } } } void AddNodePathsConnections(RefPathO srefpathconn, OnePathNode opn, double dist, double zdisp) { OnePathNode opo = srefpathconn.FromNode(); OnePath op = srefpathconn.op; assert opn == srefpathconn.ToNode(); if (opo.proxdist != -1.0) return; double addd; double addzdisp; // line is either zero length or not connected if (op.IsDropdownConnective()) { if (!bDropdownConnectiveTraversed) return; addd = 0.0; addzdisp = 0.0; } // adjust the value so that centrelines don't get used for connecting in favour else if (op.linestyle == SketchLineStyle.SLS_CENTRELINE) { if (!bCentrelineTraversed) return; addd = op.linelength * fcenlinelengthfactor; addzdisp = 0.0; } else if (op.IsZSetNodeConnective()) { addd = op.linelength; addzdisp = (opo == op.pnstart ? op.plabedl.nodeconnzsetrelative : -op.plabedl.nodeconnzsetrelative); } else if (op.IsSketchFrameConnective()) { addd = op.linelength; addzdisp = (opo == op.pnstart ? op.plabedl.sketchframedef.sfnodeconnzsetrelative : -op.plabedl.sketchframedef.sfnodeconnzsetrelative); } // standard addition else { addd = op.linelength; addzdisp = 0.0; } prioqueue.offer(new parainstance(dist + addd, zdisp + addzdisp, opo)); } } ///////////////////////////////////////////// // weights from centrelines ///////////////////////////////////////////// class ProximityDerivation { List vnodes; // OnePathNode List vpaths; // OnePath OneSketch os; int ncentrelinenodes = 0; Parainstancequeue parainstancequeue; double distmincnode = 0.0; double distmaxcnode = 0.0; double distmax = 0.0; RefPathO srefpathconn = new RefPathO(); // reused object ///////////////////////////////////////////// ProximityDerivation(OneSketch los) { // make the array parallel to the nodes os = los; vnodes = os.vnodes; vpaths = os.vpaths; parainstancequeue = new Parainstancequeue(); // find the centreline nodes; reset the proxdists ncentrelinenodes = 0; for (OnePathNode opn : vnodes) { opn.proxdist = -1.0; if (opn.IsCentrelineNode()) ncentrelinenodes++; } } ///////////////////////////////////////////// void ShortestPathsToCentrelineNodesSetup(OnePathNode sopn, OnePath sop) { assert ((sopn == null) != (sop == null)); assert parainstancequeue.proxdistsetlist.isEmpty(); for (OnePathNode opn : vnodes) assert opn.proxdist == -1.0; // make the queue and eat through it. distmincnode = -1.0; distmaxcnode = -1.0; distmax = 0.0; // start on node or midpoint of path assert parainstancequeue.prioqueue.isEmpty(); if (sopn != null) parainstancequeue.AddNode(sopn, distmax, 0.0); else { distmax = sop.linelength / 2; parainstancequeue.AddNode(sop.pnstart, distmax, 0.0); parainstancequeue.AddNode(sop.pnend, distmax, 0.0); } } ///////////////////////////////////////////// // generates the full shortest path diagram from this node int ShortestPathsToCentrelineNodes(OnePathNode sopn, OnePathNode[] cennodes, double[] zdispcennodes) { assert (zdispcennodes == null) || (zdispcennodes.length == cennodes.length); ShortestPathsToCentrelineNodesSetup(sopn, null); // eat through the queue int icennodes = 0; OnePathNode substitutecennode = sopn; double substitutecennodezdisp = 0.0; while (!parainstancequeue.prioqueue.isEmpty()) { parainstance pi = parainstancequeue.prioqueue.poll(); if (pi.opn.proxdist != -1.0) continue; distmax = pi.sdist; parainstancequeue.AddNode(pi.opn, distmax, pi.zdisp); if (pi.opn.IsCentrelineNode()) { distmaxcnode = distmax; // we're looking for the closest centreline nodes // or grab the one with the lowest value in the sort if none emerge in this connected component if (cennodes != null) { if (zdispcennodes != null) zdispcennodes[icennodes] = pi.zdisp; cennodes[icennodes++] = pi.opn; if (icennodes == cennodes.length) break; // we've now got enough centreline nodes } } else if ((cennodes != null) && (icennodes == 0) && (substitutecennode.compareTo(pi.opn) > 0)) { substitutecennode = pi.opn; substitutecennodezdisp = pi.zdisp; } } parainstancequeue.prioqueue.clear(); if (cennodes != null) { // use the default topleft node if no centreline nodes were found to tie to if (icennodes == 0) { if (zdispcennodes != null) zdispcennodes[0] = substitutecennodezdisp; cennodes[0] = substitutecennode; icennodes = 1; } for (int i = icennodes; i < cennodes.length; i++) cennodes[icennodes++] = null; } return icennodes; } ///////////////////////////////////////////// OnePath EstSubsetToCen(OnePath op, OnePathNode copn, boolean bdatetype) { assert copn.IsCentrelineNode(); assert bdatetype || op.vssubsets.isEmpty(); double xmv = (op.pnstart.pn.getX() + op.pnend.pn.getX()) / 2 - copn.pn.getX(); double ymv = (op.pnstart.pn.getY() + op.pnend.pn.getY()) / 2 - copn.pn.getY(); double maxdot = 0.0; OnePath res = null; // pick an edge by closest dot-product srefpathconn.ccopy(copn.ropconn); do { OnePath cop = srefpathconn.op; // if bdatetype should select one with a __date__ thing in it for sure if ((srefpathconn.op.linestyle == SketchLineStyle.SLS_CENTRELINE) && !srefpathconn.op.vssubsets.isEmpty()) { assert copn == srefpathconn.ToNode(); OnePathNode ocopn = srefpathconn.FromNode(); double xcv = (ocopn.pn.getX() - copn.pn.getX()); double ycv = (ocopn.pn.getY() - copn.pn.getY()); double ldot = Math.abs(xcv * xmv + ycv * ymv); if ((res == null) || (ldot > maxdot)) res = cop; } } while (!srefpathconn.AdvanceRoundToNode(copn.ropconn)); return res; } ///////////////////////////////////////////// // generates the full shortest path diagram from this node OnePath EstClosestCenPath(OnePath op, boolean bdatetype) { ShortestPathsToCentrelineNodesSetup(null, op); // eat through the queue OnePath opres = null; while (!parainstancequeue.prioqueue.isEmpty()) { parainstance pi = parainstancequeue.prioqueue.poll(); if (pi.opn.proxdist == -1.0) { distmax = pi.sdist; parainstancequeue.AddNode(pi.opn, distmax, 0.0); if (pi.opn.IsCentrelineNode()) { OnePath cop = EstSubsetToCen(op, pi.opn, bdatetype); if (cop != null) { opres = cop; parainstancequeue.prioqueue.clear(); break; } } } } // reset for next application for (OnePathNode lopn : parainstancequeue.proxdistsetlist) lopn.proxdist = -1.0; parainstancequeue.proxdistsetlist.clear(); return opres; } ///////////////////////////////////////////// void PrintProxOneNode(OnePathNode[] copn) { for (int j = 0; j < copn.length; j++) { OnePathNode cpn = copn[j]; if (cpn != null) { System.out.print(", "); System.out.print(vnodes.indexOf(cpn)); System.out.print(", "); System.out.print(cpn.pnstationlabel); System.out.print(", "); System.out.print(cpn.proxdist); } else System.out.print(", -1, , -1"); } // reset for next application for (OnePathNode lopn : parainstancequeue.proxdistsetlist) lopn.proxdist = -1.0; parainstancequeue.proxdistsetlist.clear(); } ///////////////////////////////////////////// // generates the full shortest path diagram from this node void PrintCNodeProximity(int nnodes) // number of nodes we print { System.out.println("****** BEGIN PRINT PROXIMITIES ******"); // centrelinenodes by dist OnePathNode[] copn = new OnePathNode[Math.min(ncentrelinenodes, nnodes)]; for (OnePathNode opn : vnodes) opn.proxdist = -1.0; // work through each of the nodes and calculate for them. for (int i = 0; i < vnodes.size(); i++) { OnePathNode opn = vnodes.get(i); if (opn.IsCentrelineNode()) { System.out.print("station, "); System.out.print(i); System.out.print(", "); System.out.print(opn.pnstationlabel); } else { ShortestPathsToCentrelineNodes(opn, copn, null); System.out.print("node, "); System.out.print(i); PrintProxOneNode(copn); } System.out.println(""); // newline } // do the labels for (OnePath op : vpaths) { if ((op.linestyle == SketchLineStyle.SLS_CONNECTIVE) && (op.plabedl != null) && !op.plabedl.drawlab.equals("")) { ShortestPathsToCentrelineNodes(op.pnstart, copn, null); System.out.print("label, "); System.out.print(op.plabedl.sfontcode); System.out.print(", "); System.out.print(op.plabedl.drawlab.replace('\n', ' ')); PrintProxOneNode(copn); System.out.println(""); // newline } } System.out.println("****** END PRINT PROXIMITIES ******"); } ///////////////////////////////////////////// // generates the full shortest path diagram from this node void SetZaltsFromCNodesByInverseSquareWeight(OneSketch los) { parainstancequeue.bDropdownConnectiveTraversed = false; parainstancequeue.bCentrelineTraversed = false; // reset all the connective nodes ones for (OnePathNode opn : vnodes) { opn.proxdist = -1.0; if (opn.pnstationlabel == OnePathNode.strConnectiveNode) opn.pnstationlabel = null; assert ((opn.pnstationlabel == null) || !opn.pnstationlabel.equals(OnePathNode.strConnectiveNode)); } // just averages over 4 nodes assert os == los; int ncopn = Math.max(1, Math.min(ncentrelinenodes, 4)); OnePathNode[] copn = new OnePathNode[ncopn]; double[] zdispcennodes = new double[ncopn]; // set all the unset zalts boolean bfirst = true; for (OnePathNode opn : vnodes) { if (!opn.IsCentrelineNode()) { ShortestPathsToCentrelineNodes(opn, copn, zdispcennodes); double tweight = 0.0; double zaltsum = 0.0; for (int j = 0; j < copn.length; j++) { OnePathNode cpn = copn[j]; if (cpn == null) { if (j == 0) { tweight = 1.0; zaltsum = 0.0; } break; } assert cpn.proxdist != -1.0; if (cpn.proxdist == 0.0) // station node case { tweight = 1.0; assert zdispcennodes[j] == 0.0; zaltsum = cpn.zalt + zdispcennodes[j]; break; } double weight = 1.0 / (cpn.proxdist * cpn.proxdist); zaltsum += (cpn.zalt + zdispcennodes[j]) * weight; tweight += weight; } if (tweight == 0.0) tweight = 1.0; opn.zalt = (float)(zaltsum / tweight); // reset for next application for (OnePathNode lopn : parainstancequeue.proxdistsetlist) { assert lopn.proxdist >= 0.0; lopn.proxdist = -1.0; } parainstancequeue.proxdistsetlist.clear(); } if ((os.zaltlo > opn.zalt) || bfirst) os.zaltlo = opn.zalt; if ((os.zalthi < opn.zalt) || bfirst) os.zalthi = opn.zalt; bfirst = false; } } }; tunnelx-20140102.orig/src/SymbolStyleAttr.java0000644000000000000000000000707011762432750016055 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2007 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.BasicStroke; import java.awt.Font; import java.awt.Color; import java.util.List; import java.util.ArrayList; import java.awt.geom.Rectangle2D; ///////////////////////////////////////////// class SymbolStyleAttr { String symbolname; int iautsymboverwrite; // style of button (filled in after construction) String autsymbdesc; // filled in after construction float symbolstrokewidth = -1.0F; Color symbolcolour = SubsetAttr.coldefalt; List ssymbolbs = null; BasicStroke symbolstroke = null; ///////////////////////////////////////////// SymbolStyleAttr(String lsymbolname) { symbolname = lsymbolname; } ///////////////////////////////////////////// // copy of whole style SymbolStyleAttr(SymbolStyleAttr ssa) { symbolname = ssa.symbolname; iautsymboverwrite = ssa.iautsymboverwrite; autsymbdesc = ssa.autsymbdesc; symbolstrokewidth = ssa.symbolstrokewidth; symbolcolour = ssa.symbolcolour; ssymbolbs = new ArrayList(); ssymbolbs.addAll(ssa.ssymbolbs); // or should copy? } ///////////////////////////////////////////// void FillMissingAttribsSSA(SymbolStyleAttr ssa) { assert (ssa == null) || symbolname.equals(ssa.symbolname); if (symbolstrokewidth == -1.0F) symbolstrokewidth = (ssa != null ? ssa.symbolstrokewidth : 1); if (symbolcolour == SubsetAttr.coldefalt) symbolcolour = (ssa != null ? ssa.symbolcolour : Color.blue); if ((ssymbolbs == null) && ((ssa == null) || (ssa.ssymbolbs != null))) { ssymbolbs = new ArrayList(); if (ssa != null) ssymbolbs.addAll(ssa.ssymbolbs); } // set font up if we have enough properties if (ssa == null) symbolstroke = new BasicStroke(symbolstrokewidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, symbolstrokewidth * 5.0F); } ///////////////////////////////////////////// public void SetUp(List lvgsymbolstsketches) { for (SSymbolBase ssb : ssymbolbs) { // now match each with symbol name to sketch for (OneSketch lgsym : lvgsymbolstsketches) { if (lgsym.sketchsymbolname.equals(ssb.gsymname)) { ssb.gsym = lgsym; break; } } if (ssb.gsym == null) TN.emitWarning("no match for symbol name " + ssb.gsymname); else if ((ssb.gsym.cliparea != null) && (ssb.gsym.cliparea.aarea != null) && !ssb.bScaleable) { Rectangle2D sbound = ssb.gsym.cliparea.aarea.getBounds2D(); ssb.avgsymdim = (sbound.getWidth() + sbound.getHeight()) * Math.abs(ssb.fpicscale) / 2; // far too many of these. I thought they were reused. //System.out.println("sym dym " + ssb.avgsymdim + " for symbol name " + ssb.gsymname); } } } } tunnelx-20140102.orig/src/SVGAreas.java0000644000000000000000000000744111762432750014351 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2006 Martin Green, Julian Todd // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.util.SortedSet; import java.io.IOException; import java.lang.String; import java.awt.geom.PathIterator; class SVGAreas { private float tunnelunit = 0.1F; //length of tunnel unit in meters private float xoffset = 0F; private float yoffset = 0F; private int id = 0; //The next id to use public SVGAreas(LineOutputStream los, SortedSet vsareas) throws IOException { WriteHeader(los); for (OneSArea osa : vsareas) WriteArea(los, osa); WriteFooter(los); } // open and close void WriteHeader(LineOutputStream los) throws IOException { TNXML.chconvleng = TNXML.chconvlengWSP; // a complete hack to stop &space; getting in here assert false; // not used los.WriteLine("\n"); los.WriteLine(""); los.WriteLine(TNXML.xcomopen(0, "svg", "xmlns", "http://www.w3.org/2000/svg", "version", "1.1")); los.WriteLine(TNXML.xcomtext(1, "title", "Tunnels Areas")); los.WriteLine(TNXML.xcomtext(1, "desc", "This file solely contains the calculated areas for Tunnel, you need a view.svg file to see anything.")); los.WriteLine(TNXML.xcomopen(1, "defs")); } void WriteFooter(LineOutputStream los) throws IOException { los.WriteLine(TNXML.xcomclose(1, "defs")); los.WriteLine(TNXML.xcomclose(0, "svg")); TNXML.chconvleng = TNXML.chconvlengWSP; } static float[] coords = new float[6]; //Used to get the position of line segments void WriteArea(LineOutputStream los, OneSArea oa) throws IOException { //Set svg id to area String sid = new String(String.valueOf(this.id)); this.id=this.id+1; oa.setId(sid); //Generate list of classes String classes = new String(""); for (int j = 0; j < oa.vssubsetattrs.size(); j++) { if(j!=0) classes = classes + " "; classes = classes + oa.vssubsetattrs.get(j).subsetname;//Why does this not work? } //Generate d the list of commands to generate points String d = new String(); PathIterator it = oa.gparea.getPathIterator(null); for (int j=0;!it.isDone();j=1) { if(j!=0) d = d + " "; int type = it.currentSegment(coords);//coords of the segment are returned if (type == PathIterator.SEG_MOVETO) { d = d + "M" + (coords[0] - xoffset) + " " + (coords[1] - yoffset); } else if (type == PathIterator.SEG_LINETO) { d = d + " L" + (coords[0] - xoffset) + " " + (coords[1] - yoffset); } else if (type == PathIterator.SEG_CUBICTO) { d = d + " C" + (coords[0] - xoffset) + " " + (coords[1] - yoffset) + " " + (coords[2] - xoffset) + " " + (coords[3] - yoffset) + " " + (coords[4] - xoffset) + " " + (coords[5] - yoffset); } it.next(); } //Write line los.WriteLine(TNXML.xcom(2, "path", "id", sid, "class", classes, "d", d, "z", String.valueOf(oa.zalt))); } } tunnelx-20140102.orig/src/SketchSubsetPanel.java0000644000000000000000000005503712261213471016321 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2004 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import javax.swing.JComboBox; import javax.swing.JPanel; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JToggleButton; import javax.swing.JTextField; import javax.swing.JTextArea; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JScrollPane; import javax.swing.ScrollPaneConstants; import javax.swing.DefaultListModel; import javax.swing.event.ListSelectionListener; import javax.swing.event.ListSelectionEvent; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JTree; import javax.swing.tree.TreePath; import javax.swing.tree.TreeNode; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.event.TreeSelectionListener; import javax.swing.event.TreeSelectionEvent; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.Insets; import java.awt.Component; import java.util.List; import java.util.ArrayList; import java.util.Set; import java.util.HashSet; import java.util.Map; import java.util.HashMap; import javax.swing.plaf.basic.BasicComboBoxRenderer; ///////////////////////////////////////////// class SubsetStyleComboBoxRenderer extends BasicComboBoxRenderer { public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { //System.out.println("yipyip" + index); SubsetAttrStyle sas = (SubsetAttrStyle)value; if (isSelected) { setBackground(list.getSelectionBackground()); setForeground(list.getSelectionForeground()); if (sas != null) list.setToolTipText(sas.stylename); } else { setBackground(list.getBackground()); setForeground(list.getForeground()); } setFont(list.getFont()); setText((sas == null) ? "" : sas.shortstylename); return this; } }; ///////////////////////////////////////////// class SketchSubsetPanel extends JPanel { SketchDisplay sketchdisplay; JComboBox jcbsubsetstyles; JTree pansksubsetstree = new JTree(); SubsetAttrStyle sascurrent = null; // says what lists the current selection is in List vsubsetsinarea = new ArrayList(); List vsubsetspartinarea = new ArrayList(); JComboBox subsetlistsel = new JComboBox(); ///////////////////////////////////////////// SketchSubsetPanel(SketchDisplay lsketchdisplay) { super(new BorderLayout()); sketchdisplay = lsketchdisplay; JPanel jpbuts = new JPanel(new GridLayout(0, 2)); jpbuts.add(new JButton(sketchdisplay.acaReflect)); JButton butacaAddToSubset = new JButton(sketchdisplay.acaAddToSubset); butacaAddToSubset.setMargin(new Insets(2, 3, 2, 3)); jpbuts.add(butacaAddToSubset); JButton butacaRemoveFromSubset = new JButton(sketchdisplay.acaRemoveFromSubset); butacaRemoveFromSubset.setMargin(new Insets(2, 3, 2, 3)); jpbuts.add(new JButton(sketchdisplay.acaCleartreeSelection)); jpbuts.add(butacaRemoveFromSubset); jpbuts.add(new JLabel("subset style:", JLabel.RIGHT)); jcbsubsetstyles = new JComboBox(); jcbsubsetstyles.setRenderer(new SubsetStyleComboBoxRenderer()); jcbsubsetstyles.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { SubsetSelectionChanged(false); } } ); jpbuts.add(jcbsubsetstyles); subsetlistsel.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { int i = subsetlistsel.getSelectedIndex(); //System.out.println("Selind " + i + " " + vsubsetsinarea.size() + " " + vsubsetspartinarea.size()); String ssub = (i >= vsubsetsinarea.size() + 1 ? vsubsetspartinarea.get(i - 1 - vsubsetsinarea.size()) : (i >= 1 ? vsubsetsinarea.get(i - 1) : "")); SelectSubset(ssub); } } ); pansksubsetstree.setRootVisible(false); pansksubsetstree.setShowsRootHandles(true); pansksubsetstree.setEditable(true); pansksubsetstree.setExpandsSelectedPaths(true); pansksubsetstree.addTreeSelectionListener(new TreeSelectionListener() { public void valueChanged(TreeSelectionEvent e) { sketchdisplay.selectedsubsetstruct.UpdateTreeSubsetSelection(pansksubsetstree); } } ); add(jpbuts, BorderLayout.NORTH); JScrollPane jsp = new JScrollPane(pansksubsetstree); jsp.setPreferredSize(new Dimension(150, 150)); add(jsp, BorderLayout.CENTER); add(subsetlistsel, BorderLayout.SOUTH); } ///////////////////////////////////////////// // this is all pretty annoying and explains why trees are not right here anymore // just does the tree to a depth of two void SelectSubset(String ssub) { if ((sascurrent == null) || ssub.equals("")) return; for (int i = 0; i < sascurrent.dmroot.getChildCount(); i++) { TreeNode tn1 = sascurrent.dmroot.getChildAt(i); for (int j = 0; j < tn1.getChildCount(); j++) { DefaultMutableTreeNode tn2 = (DefaultMutableTreeNode)tn1.getChildAt(j); if (tn2.getUserObject() instanceof String) { String tn2v = (String)tn2.getUserObject(); if (tn2v.equals(ssub)) { TreePath tpres = new TreePath(sascurrent.dmroot).pathByAddingChild(tn1).pathByAddingChild(tn2); pansksubsetstree.setSelectionPath(tpres); return; } } } } } ///////////////////////////////////////////// int Getcbsubsetstyleindex(String sfstyle) { for (int i = 0; i < jcbsubsetstyles.getItemCount(); i++) if (((SubsetAttrStyle)jcbsubsetstyles.getItemAt(i)).stylename.equals(sfstyle)) return i; return -1; } ///////////////////////////////////////////// void SubsetSelectionChanged(boolean bjustframetree) { sascurrent = (SubsetAttrStyle)jcbsubsetstyles.getSelectedItem(); System.out.println(" SubsetSelectionChanged " + sascurrent); sketchdisplay.sketchgraphicspanel.ClearSelection(true); if (sascurrent != null) { sascurrent.TreeListUnattributedSubsets(sketchdisplay.sketchgraphicspanel.tsketch.vpaths); pansksubsetstree.setModel(sascurrent.dmtreemod); sketchdisplay.sketchgraphicspanel.tsketch.SetSubsetAttrStyle(sascurrent, sketchdisplay.sketchlinestyle.pthstyleareasigtab.sketchframedefCopied); sketchdisplay.sketchgraphicspanel.sketchgrid = sascurrent.sketchgrid; sketchdisplay.selectedsubsetstruct.UpdateTreeSubsetSelection(pansksubsetstree); if (!bjustframetree) { sketchdisplay.sketchlinestyle.symbolsdisplay.ReloadSymbolsButtons(sascurrent); sketchdisplay.sketchlinestyle.pthstylelabeltab.ReloadLabelsCombo(sascurrent); } sascurrent.TreeListFrameDefCopiedSubsets(sketchdisplay.sketchlinestyle.pthstyleareasigtab.sketchframedefCopied); } sketchdisplay.sketchgraphicspanel.SketchChanged(SketchGraphics.SC_CHANGE_SAS); } ///////////////////////////////////////////// void AddSelCentreToCurrentSubset() { if (sketchdisplay.mainbox.tunnelfilelist.activesketchindex == -1) { TN.emitMessage("Should have a sketch selected"); return; } OneSketch asketch = sketchdisplay.mainbox.GetActiveTunnelSketches().get(sketchdisplay.mainbox.tunnelfilelist.activesketchindex); String sactive = sketchdisplay.selectedsubsetstruct.GetFirstSubset(); if (sactive == null) return; PtrelLn ptrelln = new PtrelLn(); if (ptrelln.ExtractCentrelinePathCorrespondence(asketch, sketchdisplay.sketchgraphicspanel.tsketch)) { // assign the subset to each path that has correspondence. for (PtrelPLn wptreli : ptrelln.wptrel) PutToSubset(wptreli.crp, sactive, true); sketchdisplay.selectedsubsetstruct.elevset.SetIsElevStruct(true); } sketchdisplay.sketchgraphicspanel.SketchChanged(SketchGraphics.SC_CHANGE_SYMBOLS); } ///////////////////////////////////////////// void AddRemainingCentreToCurrentSubset() { String sactive = sketchdisplay.selectedsubsetstruct.GetFirstSubset(); if (sactive == null) return; for (OnePath op : sketchdisplay.sketchgraphicspanel.tsketch.vpaths) { if ((op.linestyle == SketchLineStyle.SLS_CENTRELINE) && op.vssubsets.isEmpty()) PutToSubset(op, sactive, true); } sketchdisplay.selectedsubsetstruct.elevset.SetIsElevStruct(true); sketchdisplay.sketchgraphicspanel.SketchChanged(SketchGraphics.SC_CHANGE_SYMBOLS); } ///////////////////////////////////////////// // this is the proximity graph one void PartitionRemainsByClosestSubset() { ProximityDerivation pd = new ProximityDerivation(sketchdisplay.sketchgraphicspanel.tsketch); pd.parainstancequeue.bDropdownConnectiveTraversed = true; pd.parainstancequeue.bCentrelineTraversed = true; pd.parainstancequeue.fcenlinelengthfactor = 10.0F; // factor of length added to centreline connections (to deal with vertical line cases) OnePathNode[] cennodes = new OnePathNode[pd.ncentrelinenodes]; for (OnePath op : sketchdisplay.sketchgraphicspanel.tsketch.vpaths) { if (op.vssubsets.isEmpty()) { OnePath cop = pd.EstClosestCenPath(op, false); if ((cop != null) && !cop.vssubsets.isEmpty()) op.vssubsets.add(cop.vssubsets.get(0)); } } sketchdisplay.sketchgraphicspanel.SketchChanged(SketchGraphics.SC_CHANGE_SYMBOLS); } ///////////////////////////////////////////// // this is the proximity graph one void PartitionRemainsByClosestSubsetDatetype() { ProximityDerivation pd = new ProximityDerivation(sketchdisplay.sketchgraphicspanel.tsketch); pd.parainstancequeue.bDropdownConnectiveTraversed = true; pd.parainstancequeue.bCentrelineTraversed = true; pd.parainstancequeue.fcenlinelengthfactor = 10.0F; // factor of length added to centreline connections (to deal with vertical line cases) Map datetypemap = new HashMap(); OnePathNode[] cennodes = new OnePathNode[pd.ncentrelinenodes]; for (OnePath op : sketchdisplay.sketchgraphicspanel.tsketch.vpaths) { if (op.linestyle == SketchLineStyle.SLS_CENTRELINE) continue; OnePath cop = pd.EstClosestCenPath(op, true); if (cop == null) continue; for (String ssubset : cop.vssubsets) { if (ssubset.startsWith("__date__ ")) datetypemap.put(op, ssubset); } } // now go through the areas and set them whole ones to subsets for (OneSArea osa : sketchdisplay.sketchgraphicspanel.tsketch.vsareas) { // first get the list of dates we need to select from Set areadates = new HashSet(); for (RefPathO rpo : osa.refpathsub) { String ldate = datetypemap.get(rpo.op); if (ldate != null) areadates.add(ldate); } // now find the one date we will set things to by measuring their total lengths of each (a Map attempt went bad) String bdate = null; double bdateleng = 0.0; for (String ldate : areadates) { double ldateleng = 0.0; for (RefPathO rpo : osa.refpathsub) { String lldate = datetypemap.get(rpo.op); if ((lldate != null) && lldate.equals(ldate)) ldateleng += rpo.op.linelength; } if ((bdate == null) || (ldateleng > bdateleng)) { bdate = ldate; bdateleng = ldateleng; } } System.out.println("zzzzz " + bdate + " " + bdateleng); if (bdate != null) { for (RefPathO rpo : osa.refpaths) rpo.op.vssubsets.add(bdate); } } sketchdisplay.sketchgraphicspanel.SketchChanged(SketchGraphics.SC_CHANGE_SYMBOLS); } ///////////////////////////////////////////// String GetSubOfTypeD(List vssubsets, boolean bdatetype) { if (!bdatetype) return (vssubsets.isEmpty() ? null : vssubsets.get(0)); for (String ssubset : vssubsets) { if (ssubset.startsWith("__date__ ")) return ssubset; } return null; } ///////////////////////////////////////////// void PutToSubset(OnePath op, String sactive, boolean bAdd) { // present if (op.vssubsets.contains(sactive)) { if (!bAdd) { op.vssubsets.remove(sactive); assert !op.vssubsets.contains(sactive); op.pnstart.icnodevisiblesubset--; // take off node counters op.pnend.icnodevisiblesubset--; } } // absent else if (bAdd) op.vssubsets.add(sactive); // node counters added with setvisiblecodestrings op.SetSubsetAttrs(sascurrent, sketchdisplay.sketchlinestyle.pthstyleareasigtab.sketchframedefCopied); sketchdisplay.selectedsubsetstruct.SetSubsetVisibleCodeStrings(op, bAdd); if (op.karight != null) op.karight.SetSubsetAttrsA(true, sascurrent); if (op.kaleft != null) op.kaleft.SetSubsetAttrsA(true, sascurrent); //System.out.println(" vv-icnodevisible subset " + op.pnstart.icnodevisiblesubset + " " + op.pnend.icnodevisiblesubset); } ///////////////////////////////////////////// // adds and removes from subset void PutSelToSubset(boolean bAdd) { String sactive = sketchdisplay.selectedsubsetstruct.GetFirstSubset(); if (sactive == null) return; Set opselset = sketchdisplay.sketchgraphicspanel.MakeTotalSelList(); for (OnePath op : opselset) PutToSubset(op, sactive, bAdd); sketchdisplay.selectedsubsetstruct.elevset.SetIsElevStruct(true); sketchdisplay.sketchgraphicspanel.SketchChanged(SketchGraphics.SC_CHANGE_SYMBOLS); sketchdisplay.sketchgraphicspanel.ClearSelection(true); sketchdisplay.sketchgraphicspanel.RedrawBackgroundView(); } ///////////////////////////////////////////// static RefPathO srefpathconnspare = new RefPathO(); static boolean IsWallNode(OnePathNode opn) { // find the subsets this node could be in srefpathconnspare.ccopy(opn.ropconn); do { if ((srefpathconnspare.op.linestyle == SketchLineStyle.SLS_WALL) || (srefpathconnspare.op.linestyle == SketchLineStyle.SLS_ESTWALL)) return true; } while (!srefpathconnspare.AdvanceRoundToNode(opn.ropconn)); return false; } ///////////////////////////////////////////// boolean ElevationSubset(boolean bXC) { Set opselset = sketchdisplay.sketchgraphicspanel.MakeTotalSelList(); if (opselset.isEmpty()) return TN.emitWarning("Must have a path selected"); List opclist = new ArrayList(); for (OnePath opc : opselset) { if (opc.linestyle != SketchLineStyle.SLS_CONNECTIVE) return TN.emitWarning("Must be connective paths"); if (opc.plabedl == null) opc.plabedl = new PathLabelDecode(); if (opc.plabedl.barea_pres_signal != SketchLineStyle.ASE_KEEPAREA) return TN.emitWarning("Must be simple connective paths"); opclist.add(opc); } if (!ElevSet.ReorderElevPaths(opclist)) return TN.emitWarning("Selected paths not in sequence (will try to reflect to fit later)"); sketchdisplay.sketchgraphicspanel.ClearSelection(true); OnePathNode opcfore = opclist.get(0).pnstart.ConnectingCentrelineNode(); OnePathNode opcback = opclist.get(opclist.size() - 1).pnend.ConnectingCentrelineNode(); // this delimits by spaces (could use the head and tail settings, though, and try harder in the XC case to get to a station name) String lsselevsubset; if (bXC) { if (!IsWallNode(opclist.get(0).pnstart)) return TN.emitWarning("Cross-section must start at wall node"); if (!IsWallNode(opclist.get(opclist.size() - 1).pnend)) return TN.emitWarning("Cross-section must end at wall node"); if ((opcfore != null) && (opcback != null) && (opcfore != opcback)) TN.emitWarning("choice of two stations for naming XC"); lsselevsubset = "XC " + (opcfore != null ? opcfore.pnstationlabel : (opcback != null ? opcback.pnstationlabel : "d")); } else { if ((opcfore == null) || (opcback == null)) return TN.emitWarning("Elevations must go from nodes connected to centrelines"); lsselevsubset = "ELEV " + opcfore.pnstationlabel + " " + opcback.pnstationlabel; } lsselevsubset = lsselevsubset.replaceAll("[|^]", "."); // cook up a unique name for it. // we are going to need to relay these names out when we come to importing this sketch String sselevsubset = lsselevsubset; int ni = 0; while (sascurrent.unattributedss.contains(sselevsubset) || sascurrent.xsectionss.contains(sselevsubset)) sselevsubset = lsselevsubset + " n" + (ni++); // now add these paths into the elevset sketchdisplay.selectedsubsetstruct.elevset.Clear(); //sketchdisplay.selectedsubsetstruct.elevset.selevsubset = sselevsubset; for (OnePath opc : opclist) { PutToSubset(opc, sselevsubset, true); sketchdisplay.selectedsubsetstruct.elevset.connsequence.add(opc); } OnePath opelevaxis = sketchdisplay.selectedsubsetstruct.elevset.MakeElevAxisPath(sselevsubset, bXC, opcfore, opcback); List pthstoadd = new ArrayList(); pthstoadd.add(opelevaxis); sketchdisplay.sketchgraphicspanel.CommitPathChanges(null, pthstoadd); sketchdisplay.sketchgraphicspanel.RedrawBackgroundView(); PutToSubset(opelevaxis, sselevsubset, true); //sketchdisplay.selectedsubsetstruct.elevset.elevcenpaths.add(opelevaxis); assert (sketchdisplay.selectedsubsetstruct.elevset.elevcenpaths.size() == 1) && sketchdisplay.selectedsubsetstruct.elevset.elevcenpaths.get(0) == opelevaxis; sketchdisplay.selectedsubsetstruct.elevset.SetIsElevStruct(true); assert sketchdisplay.selectedsubsetstruct.elevset.bIsElevStruct; // put this new subset into the tree structure DefaultMutableTreeNode dm = new DefaultMutableTreeNode(sselevsubset); sascurrent.xsectionss.add(0, sselevsubset); sascurrent.dmxsectionss.insert(dm, 0); sascurrent.dmtreemod.reload(sascurrent.dmxsectionss); TreePath tpsel = sascurrent.tpxsection.pathByAddingChild(dm); pansksubsetstree.setSelectionPath(tpsel); sketchdisplay.sketchgraphicspanel.repaint(); sketchdisplay.sketchgraphicspanel.SketchChanged(SketchGraphics.SC_CHANGE_SYMBOLS); return true; } ///////////////////////////////////////////// String GetNewPaperSubset(String papersize) { int ni = 1; String sspapersubset; do sspapersubset = "paper_" + papersize + "_page_" + (ni++); while (sascurrent.unattributedss.contains(sspapersubset)); DefaultMutableTreeNode dm = new DefaultMutableTreeNode(sspapersubset); sascurrent.unattributedss.add(0, sspapersubset); sascurrent.dmunattributess.insert(dm, 0); sascurrent.dmtreemod.reload(sascurrent.dmunattributess); return sspapersubset; } ///////////////////////////////////////////// void RemoveAllFromSubset() { String sactive = sketchdisplay.selectedsubsetstruct.GetFirstSubset(); if (sactive == null) return; for (OnePath op : sketchdisplay.sketchgraphicspanel.tsketch.vpaths) PutToSubset(op, sactive, false); sketchdisplay.selectedsubsetstruct.elevset.SetIsElevStruct(true); sketchdisplay.sketchgraphicspanel.SketchChanged(SketchGraphics.SC_CHANGE_SYMBOLS); sketchdisplay.sketchgraphicspanel.ClearSelection(true); sketchdisplay.sketchgraphicspanel.RedrawBackgroundView(); } ///////////////////////////////////////////// void DeleteTodeleteSubset() { sketchdisplay.sketchgraphicspanel.ClearSelection(true); sketchdisplay.sketchgraphicspanel.repaint(); if (!sketchdisplay.sketchgraphicspanel.bEditable) return; List pthstoremove = new ArrayList(); for (OnePath op : sketchdisplay.sketchgraphicspanel.tsketch.vpaths) { if (op.vssubsets.contains("todelete")) pthstoremove.add(op); } sketchdisplay.sketchgraphicspanel.CommitPathChanges(pthstoremove, null); sketchdisplay.sketchgraphicspanel.RedrawBackgroundView(); TN.emitMessage("Deleted " + pthstoremove.size() + " paths labelled as 'todelete'"); } ///////////////////////////////////////////// boolean Updateviewvpartialsubsets(List opvss, boolean bfirst) { if (bfirst) { vsubsetsinarea.addAll(opvss); return false; } // we can only move elements from the left to the right for (int i = vsubsetsinarea.size() - 1; i >= 0; i--) { if (!opvss.contains(vsubsetsinarea.get(i))) vsubsetspartinarea.add(vsubsetsinarea.remove(i)); } // file strings we have in the correct place for (int i = 0; i < opvss.size(); i++) { if (!vsubsetsinarea.contains(opvss.get(i))) { if (!vsubsetspartinarea.contains(opvss.get(i))) vsubsetspartinarea.add(opvss.get(i)); } } return false; } ///////////////////////////////////////////// void UpdateSubsetsOfPath(OnePath op) { // a single path is selected vsubsetsinarea.clear(); vsubsetspartinarea.clear(); // an area set of paths is selected (feature frigged in) if (sketchdisplay.sketchgraphicspanel.currselarea != null) { boolean bfirst = true; for (RefPathO rpo : sketchdisplay.sketchgraphicspanel.currselarea.refpaths) bfirst = Updateviewvpartialsubsets(rpo.op.vssubsets, bfirst); for (ConnectiveComponentAreas cca : sketchdisplay.sketchgraphicspanel.currselarea.ccalist) { for (OnePath sop : cca.vconnpaths) bfirst = Updateviewvpartialsubsets(sop.vssubsets, bfirst); } } else if (op != null) vsubsetsinarea.addAll(op.vssubsets); // update the subset buttons from this subsetlistsel.removeAllItems(); String subsetlistf = (!vsubsetsinarea.isEmpty() ? vsubsetsinarea.get(0) : (!vsubsetspartinarea.isEmpty() ? "(" + vsubsetspartinarea.get(0) + ")" : "")); String subsetlistsum = "List: " + vsubsetsinarea.size() + " " + (!vsubsetspartinarea.isEmpty() ? "(" + vsubsetspartinarea.size() + ")" : "") + " " + subsetlistf; subsetlistsel.addItem(subsetlistsum); for (String ssub : vsubsetsinarea) subsetlistsel.addItem(ssub); for (String ssub : vsubsetspartinarea) subsetlistsel.addItem("Part: " + ssub); subsetlistsel.validate(); } void SetSubsetStyleFromString(String sfstyle) { int newselectionindex = (!sfstyle.equals("") ? Getcbsubsetstyleindex(sfstyle) : -1); if ((newselectionindex == -1) && (jcbsubsetstyles.getSelectedIndex() == -1) && (jcbsubsetstyles.getItemCount() != 0)) newselectionindex = 0; if ((newselectionindex != -1) && (jcbsubsetstyles.getSelectedIndex() != newselectionindex)) jcbsubsetstyles.setSelectedIndex(newselectionindex); // this will cause SubsetSelectionChanged to be called else SubsetSelectionChanged(false); } } tunnelx-20140102.orig/src/PathLabelXMLparse.java0000644000000000000000000000625411762432750016207 0ustar // Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. // Jad home page: http://www.kpdus.com/jad.html // Decompiler options: packimports(3) // Source File Name: PathLabelDecode.java package Tunnel; import java.util.List; // Referenced classes of package Tunnel: // TunnelXMLparsebase, TunnelXML, PathLabelDecode, TNXML, // SketchLineStyle class PathLabelXMLparse extends TunnelXMLparsebase { PathLabelXMLparse() { sbtxt = new StringBuffer(); } boolean ParseLabel(PathLabelDecode pathlabeldecode, String s, SketchLineStyle sketchlinestyle1) { pld = pathlabeldecode; sketchlinestyle = sketchlinestyle1; if(s.indexOf('<') == -1) { pld.sfontcode = "default"; pld.drawlab = s; return true; } else { return (new TunnelXML()).ParseString(this, s) == null; } } public void startElementAttributesHandled(String s, boolean flag) { label0: { label1: { label2: { label3: { if(!s.equals(TNXML.sLRSYMBOL)) break label1; String s1 = SeStack(TNXML.sAREA_PRESENT); if(s1 == null) break label2; pld.iarea_pres_signal = 0; int i = 0; do { SketchLineStyle _tmp = sketchlinestyle; if(i >= SketchLineStyle.nareasignames) break label3; SketchLineStyle _tmp1 = sketchlinestyle; if(s1.equals(SketchLineStyle.areasignames[i])) pld.iarea_pres_signal = i; i++; } while(true); } pld.barea_pres_signal = SketchLineStyle.areasigeffect[pld.iarea_pres_signal]; } String s2 = SeStack(TNXML.sLRSYMBOL_NAME); if(s2 != null) pld.vlabsymb.add(s2); break label0; } if(s.equals(TNXML.sTAIL) || s.equals(TNXML.sHEAD)) sbtxt.setLength(0); else if(s.equals(TNXML.sLTEXT)) { sbtxt.setLength(0); pld.sfontcode = SeStack(TNXML.sLTEXTSTYLE); } else if(s.equals("br")) sbtxt.append('\n'); } } public void characters(String s) { if(sbtxt.length() != 0 && sbtxt.charAt(sbtxt.length() - 1) != '\n') sbtxt.append(' '); sbtxt.append(s); } public void endElementAttributesHandled(String s) { if(s.equals(TNXML.sHEAD)) pld.centrelinehead = sbtxt.toString(); else if(s.equals(TNXML.sTAIL)) pld.centrelinetail = sbtxt.toString(); else if(s.equals(TNXML.sLTEXT)) pld.drawlab = sbtxt.toString(); } PathLabelDecode pld; SketchLineStyle sketchlinestyle; StringBuffer sbtxt; } tunnelx-20140102.orig/src/SSymbolBase.java0000644000000000000000000000574411762432750015125 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.Color; //////////////////////////////////////////////////////////////////////////////// class SSymbolBase { // these factors should be set by the symbol itself (maybe by name). boolean bScaleable = false; // new default float fpicscale = 1.0F; // if scalable false we may scale by a fixed amount float faxisscale = 1.0F; // if scalable false we may scale by a fixed amount float faxisscaleperp = 1.0F; // further scattering in the perpendicular direction, so there is somewhere to pullback to boolean bRotateable = true; // will be false for stal symbols. // positioning parameters boolean bBuildSymbolLatticeAcrossArea; boolean bSymbolLatticeAcrossAreaPhased; boolean bBuildSymbolSpreadAlongLine; boolean bSymbolLayoutOrdered; boolean bOrientClosestAlongLine; boolean bOrientClosestPerpLine; double posdeviationprop = 1.0F; // proportional distance we can move the symbol boolean bMoveable = false; // symbol can be elsewhere other than where it is put (and so multiplicity is valid). int iLattice = 0; // non-zero means lattice, type 1 is lattice displace phased by endpoint, type 2 has position always on a grid (usually not rotatable). boolean bPullback = false; // pulling back till interference. boolean bPushout = false; // pushing away till no interference. boolean bShrinkby2 = false; // add in a size change in boulder fields. boolean bAllowedOutsideArea = false; boolean bTrimByArea = true; boolean bSymbolinterferencedoesntmatter = false; boolean bFilledType = false; boolean bDeprecated = false; double posangledeviation = 0.1F; // in radians. -1.0 means anywhere. // over-rides everything else if non null Color symbolareafillcolour = null; // filling of the area if symbolareafill defined (eg water) double pulltolerance = 0.05; // 5cm. // the name of the base symbol String gsymname; OneSketch gsym = null; // this is selected by name. double avgsymdim = 0.0; // average symbol dimension along the axes int nmultiplicity = 0; int maxplaceindex = 1800; // or -1 for unlimited setting. }; tunnelx-20140102.orig/src/MainBox.java-applet0000644000000000000000000005453311762432750015562 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.io.IOException; import java.io.InputStreamReader; import java.io.BufferedReader; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.Dimension; import java.awt.Point; import javax.swing.JFrame; import javax.swing.JSplitPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.JScrollPane; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JMenuBar; import javax.swing.JOptionPane; import javax.swing.JApplet; import java.net.URL; import java.net.MalformedURLException; import java.lang.ClassLoader; import java.util.List; import java.util.ArrayList; ///////////////////////////////////////////// ///////////////////////////////////////////// // the main frame public class MainBox // extends JFrame extends JApplet // AppletConversion { // the parameters used in this main box // the survey tree TunnelTree treeview; TunnelFileList tunnelfilelist; TunnelLoader tunnelloader; OneTunnel roottunnel; OneTunnel filetunnel; URL docbaseurl; // this will keep the global sections, tubes, and sketch in it // which a station calculation is lifted into and then operated on. OneTunnel otglobal = new OneTunnel("Global", null); // maybe should be moved into stationcalculation. // the class that loads and calculates the positions of everything from the data in the tunnels. StationCalculation sc = new StationCalculation(); // single xsection window and wireframe display SectionDisplay sectiondisplay = new SectionDisplay(); WireframeDisplay wireframedisplay = new WireframeDisplay(sectiondisplay); // the default treeroot with list of symbols. OneTunnel vgsymbols = new OneTunnel("gsymbols", null); // sketch display window SketchDisplay sketchdisplay = new SketchDisplay(this, vgsymbols); // text display of the other files. TextDisplay textdisplay = new TextDisplay(); // for previewing images in the directory. ImgDisplay imgdisplay = new ImgDisplay(); ///////////////////////////////////////////// void MainRefresh() { roottunnel.RefreshTunnelFromSVX(); treeview.RefreshListBox(roottunnel); // or load filetunnel. } ///////////////////////////////////////////// void MainClear() { roottunnel = new OneTunnel("root", null); roottunnel.IntroduceSubTunnel(vgsymbols); treeview.RefreshListBox(roottunnel); } ///////////////////////////////////////////// void LoadTunnelDirectoryTree(String filetunnname, FileAbstraction tunneldirectory) { filetunnel = roottunnel.IntroduceSubTunnel(new OneTunnel(filetunnname, null)); tunnelloader = new TunnelLoader(vgsymbols, sketchdisplay.sketchlinestyle); try { FileAbstraction.FileDirectoryRecurse(filetunnel, tunneldirectory); tunnelloader.LoadFilesRecurse(filetunnel); } catch (IOException ie) { TN.emitWarning(ie.toString()); ie.printStackTrace(); } catch (NullPointerException e) { TN.emitWarning(e.toString()); e.printStackTrace(); }; // update any symbols information that may have showed up in the process if (sketchdisplay.sketchlinestyle.bsubsetattributesneedupdating) sketchdisplay.sketchlinestyle.UpdateSymbols(false); } ///////////////////////////////////////////// void MainOpen(boolean bClearFirst, boolean bAuto, int ftype) { SvxFileDialog sfiledialog = SvxFileDialog.showOpenDialog(TN.currentDirectory, this, ftype, bAuto); if ((sfiledialog == null) || ((sfiledialog.svxfile == null) && (sfiledialog.tunneldirectory == null))) return; TN.currentDirectory = sfiledialog.getSelectedFileA(); if (sfiledialog.tunneldirectory == null) { if (!sfiledialog.svxfile.canRead()) { JOptionPane.showMessageDialog(this, "Cannot open svx file: " + sfiledialog.svxfile.getName()); return; } TN.emitMessage("Loading survey file " + sfiledialog.svxfile.getName()); } else if (!sfiledialog.tunneldirectory.isDirectory()) { JOptionPane.showMessageDialog(this, "Cannot open tunnel directory: " + sfiledialog.tunneldirectory.getName()); return; } if (bClearFirst) MainClear(); String soname = (sfiledialog.tunneldirectory == null ? sfiledialog.svxfile.getName() : sfiledialog.tunneldirectory.getName()); int il = soname.indexOf('.'); if (il != -1) soname = soname.substring(0, il); // put the tunnel in String filetunnname = soname.replace(' ', '_').replace('\t', '_'); // can't cope with spaces. // loading directly from a tunnel directory tree if (sfiledialog.tunneldirectory != null) LoadTunnelDirectoryTree(filetunnname, sfiledialog.tunneldirectory); // loading a survex file else { int lndowntunnels = roottunnel.vdowntunnels.size(); // allows for more than one SVX to be loaded in new SurvexLoader(sfiledialog.svxfile, roottunnel, sfiledialog.bReadCommentedXSections); if (roottunnel.vdowntunnels.size() == lndowntunnels + 1) { filetunnel = roottunnel.vdowntunnels.get(lndowntunnels); // case where the tunnel directory is automatically set if (filetunnel.tundirectory != null) MainSetXMLdir(filetunnel.tundirectory); } else TN.emitWarning("svx root contains " + (roottunnel.vdowntunnels.size() - lndowntunnels) + " primary *begin blocks instead of one"); if (!roottunnel.vexports.isEmpty() || !roottunnel.vlegs.isEmpty()) TN.emitWarning("Cave data outside *begin, missing data possible"); } MainRefresh(); } ///////////////////////////////////////////// void LoadAllSketchesRecurse(OneTunnel tunnel) { for (OneSketch tsketch : tunnel.tsketches) { if (!tsketch.bsketchfileloaded) tunnelloader.LoadSketchFile(tunnel, tsketch, true); } for (OneTunnel downtunnel : tunnel.vdowntunnels) LoadAllSketchesRecurse(downtunnel); } ///////////////////////////////////////////// void MainSetXMLdir(FileAbstraction ltundirectory) { if (ltundirectory == null) { SvxFileDialog sfiledialog = SvxFileDialog.showSaveDialog(TN.currentDirectory, this, SvxFileDialog.FT_DIRECTORY); if (sfiledialog == null) return; TN.currentDirectory = sfiledialog.getSelectedFileA(); ltundirectory = sfiledialog.tunneldirectory; } if ((ltundirectory != null) && (filetunnel != null)) { TN.emitMessage("Loading all sketches"); LoadAllSketchesRecurse(filetunnel); TN.emitMessage("Setting tunnel directory tree" + ltundirectory.getName()); FileAbstraction.ApplyFilenamesRecurse(filetunnel, ltundirectory); tunnelfilelist.tflist.repaint(); } } ///////////////////////////////////////////// void MainSaveXMLdir() { // we could save just from selected place on down. if ((filetunnel != null) && (filetunnel.tundirectory != null)) TunnelSaver.SaveFilesRoot(filetunnel, false); else TN.emitWarning("Need to set the XML dir first"); // save any edited symbols TunnelSaver.SaveFilesRoot(vgsymbols, true); tunnelfilelist.tflist.repaint(); } ///////////////////////////////////////////// void ApplySplineChange() { } ///////////////////////////////////////////// void MainExit() { if (JOptionPane.showConfirmDialog(this, "Are you sure you want to quit?", "Quit?", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) System.exit(0); } ///////////////////////////////////////////// // build a wireframe window. void ViewWireframe(boolean bSingleTunnel, OneTunnel disptunnel) { if (disptunnel == null) return; if (bSingleTunnel) { disptunnel.ResetUniqueBaseStationTunnels(); //if ((tunnelfilelist.activetunnel.posfile != null) && (tunnelfilelist.activetunnel.vposlegs == null)) // TunnelLoader.LoadPOSdata(tunnelfilelist.activetunnel); if (sc.CalcStationPositions(disptunnel, otglobal.vstations, disptunnel.name) <= 0) return; wireframedisplay.ActivateWireframeDisplay(disptunnel, true); } else { sc.CopyRecurseExportVTunnels(otglobal, disptunnel, true); if ((tunnelfilelist.activetunnel.posfile != null) && (tunnelfilelist.activetunnel.vposlegs == null)) TunnelLoader.LoadPOSdata(tunnelfilelist.activetunnel); tunnelfilelist.tflist.repaint(); if (sc.CalcStationPositions(otglobal, null, disptunnel.name) <= 0) return; otglobal.mdatepos = disptunnel.mdatepos; wireframedisplay.ActivateWireframeDisplay(otglobal, false); } } ///////////////////////////////////////////// boolean OperateProcess(ProcessBuilder pb, String pname) { try { pb.redirectErrorStream(true); Process p = pb.start(); BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())); String line; while ((line = br.readLine()) != null) TN.emitMessage(" " + pname + ":: " + line); int ires = p.waitFor(); if (ires == 0) return true; } catch (IOException ie) { TN.emitWarning("@@ caught exception"); TN.emitWarning(ie.toString()); ie.printStackTrace(); } catch (InterruptedException ie) { TN.emitWarning("@@ caught Interrupted exception"); TN.emitWarning(ie.toString()); ie.printStackTrace(); } return false; } ///////////////////////////////////////////// ///////////////////////////////////////////// // build a sketch window. void ViewSketch() { if (tunnelfilelist.activetunnel == null) TN.emitWarning("No tunnel selected"); else if (tunnelfilelist.activetxt == FileAbstraction.FA_FILE_3D) { assert tunnelfilelist.activetunnel.t3dfile != null; ProcessBuilder pb = new ProcessBuilder(TN.survexexecutabledir + "aven", tunnelfilelist.activetunnel.t3dfile.getPath()); pb.directory(tunnelfilelist.activetunnel.tundirectory.localfile); OperateProcess(pb, "aven.exe"); } else if (tunnelfilelist.activetxt == FileAbstraction.FA_FILE_XML_FONTCOLOURS) { textdisplay.ActivateTextDisplay(tunnelfilelist.activetunnel, tunnelfilelist.activetxt, tunnelfilelist.activesketchindex); // for seeing in text window // used to do the reload /*sketchdisplay.sketchlinestyle.bsubsetattributesneedupdating = true; tunnelfilelist.tflist.repaint(); // used to make it at least blink tunnelloader.ReloadFontcolours(tunnelfilelist.activetunnel, tunnelfilelist.activesketchindex); if (sketchdisplay.sketchlinestyle.bsubsetattributesneedupdating) sketchdisplay.sketchlinestyle.UpdateSymbols(false); if (sketchdisplay.sketchgraphicspanel.tsketch != null) SketchGraphics.SketchChangedStatic(SketchGraphics.SC_CHANGE_SAS, sketchdisplay.sketchgraphicspanel.tsketch, sketchdisplay); tunnelfilelist.tflist.repaint();*/ } // now make the sketch else if (tunnelfilelist.activetxt == FileAbstraction.FA_FILE_XML_SKETCH) { // load the sketch if necessary. Then view it OneSketch activesketch = tunnelfilelist.activetunnel.tsketches.get(tunnelfilelist.activesketchindex); if (!activesketch.bsketchfileloaded) tunnelloader.LoadSketchFile(tunnelfilelist.activetunnel, activesketch, true); sketchdisplay.ActivateSketchDisplay(tunnelfilelist.activetunnel, activesketch, true); } // rest are text types else if ((tunnelfilelist.activetxt == FileAbstraction.FA_FILE_SVX) || (tunnelfilelist.activetxt == FileAbstraction.FA_FILE_XML_MEASUREMENTS) || (tunnelfilelist.activetxt == FileAbstraction.FA_FILE_XML_EXPORTS) || (tunnelfilelist.activetxt == FileAbstraction.FA_FILE_POS)) textdisplay.ActivateTextDisplay(tunnelfilelist.activetunnel, tunnelfilelist.activetxt, -1); tunnelfilelist.tflist.repaint(); } ///////////////////////////////////////////// // make a new sketch void NewSketch() { if (tunnelfilelist.activetunnel == null) return; // if new symbols type we should be able to edit the name before creating. // find a unique new name. (this can go wrong, but tired of it). int nsknum = tunnelfilelist.activetunnel.tsketches.size() - 1; // determin if this is the sketch type (needs refining) OneSketch tsketch = new OneSketch(tunnelfilelist.activetunnel.GetUniqueSketchFileName(), tunnelfilelist.activetunnel); if (tunnelfilelist.activetunnel == vgsymbols) { tsketch.sketchsymbolname = tsketch.sketchfile.getName(); TN.emitMessage("SketchSymbolName: " + tsketch.sketchsymbolname); tsketch.bSymbolType = true; } tsketch.SetupSK(); tsketch.bsketchfilechanged = true; // load into the structure and view it. assert tsketch.bsketchfileloaded; tunnelfilelist.activetunnel.tsketches.add(tsketch); tunnelfilelist.RemakeTFList(); tunnelfilelist.tflist.setSelectedIndex(tunnelfilelist.isketche - 1); tunnelfilelist.UpdateSelect(true); // doubleclicks it. } ///////////////////////////////////////////// void SvxGenPosfile(OneTunnel ot) { if ((ot == null) || (ot == vgsymbols) || (ot.tundirectory == null) || (ot.svxfile == null)) return; if (TN.survexexecutabledir.equals("")) TN.emitError("Missing from fontcolours"); // overwrite those intermediate files if they exist, because there can only be one of each per directory. // FileAbstraction l3dfile = (ot.t3dfile != null ? ot.t3dfile : FileAbstraction.MakeDirectoryAndFileAbstraction(ot.tundirectory, TN.setSuffix(ot.svxfile.getName(), TN.SUFF_3D))); FileAbstraction lposfile = (ot.posfile != null ? ot.posfile : FileAbstraction.MakeDirectoryAndFileAbstraction(ot.tundirectory, TN.setSuffix(ot.svxfile.getName(), TN.SUFF_POS))); List cmds = new ArrayList(); cmds.add(TN.survexexecutabledir + "cavern"); cmds.add("--no-auxiliary-files"); cmds.add("--quiet"); // or -qq for properly quiet cmds.add("-o"); cmds.add(l3dfile.getPath()); cmds.add(ot.svxfile.getPath()); ProcessBuilder pb = new ProcessBuilder(cmds); pb.directory(ot.tundirectory.localfile); if (OperateProcess(pb, "cavern.exe")) { cmds.clear(); cmds.add(TN.survexexecutabledir + "3dtopos"); cmds.add(l3dfile.getPath()); cmds.add(lposfile.getPath()); //System.out.println("SVX path: " + tunnelfilelist.activetunnel.svxfile.getPath()); ProcessBuilder pb3 = new ProcessBuilder(cmds); pb3.directory(ot.tundirectory.localfile); if (OperateProcess(pb3, "cavern.exe")) { ot.t3dfile = l3dfile; ot.posfile = lposfile; ot.vposlegs = null; //LoadPOSdata(tunnel); tunnelfilelist.RemakeTFList(); } } tunnelfilelist.RemakeTFList(); } ///////////////////////////////////////////// ///////////////////////////////////////////// ///////////////////////////////////////////// public MainBox() { // hide for AppletConversion // setTitle("TunnelX - Cave Drawing Program"); // setLocation(new Point(100, 100)); // setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); // addWindowListener(new WindowAdapter() // { public void windowClosing(WindowEvent event) { MainExit(); } } ); // applet type //docbaseurl = getDocumentBase(); //System.out.println(docbaseurl); } // need to load the fontcolours.xml which will then call in a bunch of symbols that need to be loaded // into vgsymbols. // each of these resources comes in as a name // // LoadSymbols public void init() { FileAbstraction.InitFA(); // at this point we know if it's applet or not // setup the menu items JMenuItem miClear = new JMenuItem("New"); miClear.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { MainClear(); MainRefresh(); } } ); JMenuItem miOpenXMLDir = new JMenuItem("Open XML dir..."); miOpenXMLDir.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { MainOpen(true, false, SvxFileDialog.FT_DIRECTORY); } } ); JMenuItem miOpen = new JMenuItem("Open svx..."); miOpen.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { MainOpen(true, false, SvxFileDialog.FT_SVX); } } ); JMenuItem miSetXMLDIR = new JMenuItem("Set XMLDIR"); miSetXMLDIR.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { MainSetXMLdir(null); } } ); JMenuItem miSaveXMLDIR = new JMenuItem("Save XMLDIR"); miSaveXMLDIR.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { MainSaveXMLdir(); } } ); JMenuItem miRefresh = new JMenuItem("Refreshhh"); miRefresh.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { MainRefresh(); } } ); JMenuItem miExit = new JMenuItem("Exit"); miExit.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { MainExit(); } } ); JMenuItem miWireframe = new JMenuItem("Wireframe"); miWireframe.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { ViewWireframe(true, tunnelfilelist.activetunnel); } } ); JMenuItem miSketch = new JMenuItem("View Sketch"); miSketch.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { ViewSketch(); } } ); JMenuItem miNewEmptySketch = new JMenuItem("New Empty Sketch"); miNewEmptySketch.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { NewSketch(); } } ); JMenuItem miSVXPOSfile = new JMenuItem("Survex gen Posfile"); miSVXPOSfile.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { SvxGenPosfile(tunnelfilelist.activetunnel); } } ); JMenuItem miCaveBelow = new JMenuItem("Cave Below"); miCaveBelow.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { ViewWireframe(false, tunnelfilelist.activetunnel); } } ); JMenuItem miWholeCave = new JMenuItem("Whole Cave"); miWholeCave.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { ViewWireframe(false, roottunnel); } } ); // build the layout of the menu bar JMenuBar menubar = new JMenuBar(); JMenu menufile = new JMenu("File"); menufile.add(miClear); if (!FileAbstraction.bIsApplet) // or use disable function on them to grey them out. { menufile.add(miOpenXMLDir); menufile.add(miOpen); } menufile.add(miRefresh); if (!FileAbstraction.bIsApplet) { menufile.add(miSetXMLDIR); menufile.add(miSaveXMLDIR); menufile.add(miExit); } menubar.add(menufile); JMenu menutunnel = new JMenu("Tunnel"); menutunnel.add(miSVXPOSfile); menutunnel.add(miWireframe); menutunnel.add(miSketch); menutunnel.add(miNewEmptySketch); menubar.add(menutunnel); JMenu menuview = new JMenu("View"); menuview.add(miCaveBelow); menuview.add(miWholeCave); menubar.add(menuview); setJMenuBar(menubar); // set the listener on the list //rhslist. //Add the scroll panes to a split pane JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); splitPane.setDividerLocation(200); // build the left hand area treeview = new TunnelTree(this); tunnelfilelist = new TunnelFileList(this); //JScrollPane rhsview = new JScrollPane(rhslist); // the two centre line type panels Dimension minimumSize = new Dimension(500, 300); treeview.setPreferredSize(minimumSize); tunnelfilelist.setPreferredSize(minimumSize); splitPane.setLeftComponent(treeview); splitPane.setRightComponent(tunnelfilelist); //Add the split pane to this frame getContentPane().add(splitPane); // pack(); //hide for AppletConversion setVisible(true); // load the symbols from the current working directory. // byproduct is it will load the stoke colours too sketchdisplay.sketchlinestyle.LoadSymbols(FileAbstraction.currentSymbols); assert sketchdisplay.sketchlinestyle.bsubsetattributesneedupdating; sketchdisplay.sketchlinestyle.UpdateSymbols(true); if (SketchLineStyle.strokew == -1.0F) SketchLineStyle.SetStrokeWidths(0.625F); MainClear(); } ///////////////////////////////////////////// // startup the program public static void main(String args[]) { // set the verbose flag int i = 0; while (args.length > i) { if (args[i].equals("--verbose")) { TN.bVerbose = true; i++; } else if (args[i].equals("--quiet")) { TN.bVerbose = false; i++; } break; } // start-up FileAbstraction.bIsApplet = false; TN.currentDirectory = FileAbstraction.MakeCurrentUserDirectory(); MainBox mainbox = new MainBox(); mainbox.init(); // the init gets called // do the filename if (args.length == i + 1) { TN.currentDirectory = FileAbstraction.MakeWritableFileAbstraction(args[i]); TN.currentDirectory = FileAbstraction.MakeCanonical(TN.currentDirectory); mainbox.MainOpen(true, true, (TN.currentDirectory.isDirectory() ? SvxFileDialog.FT_DIRECTORY : SvxFileDialog.FT_SVX)); } } ///////////////////////////////////////////// boolean bFileLoaded = false; public void start() { assert FileAbstraction.bIsApplet; if (bFileLoaded) return; ClassLoader cl = MainBox.class.getClassLoader(); TN.currentDirectory = new FileAbstraction(); // uncomment for AppletConversion TN.currentDirectory.localurl = cl.getResource(getParameter("cavedir") + "/"); String fullcavedir = getParameter("fullcavedir"); if (fullcavedir != null) { try { TN.currentDirectory.localurl = new URL(fullcavedir); } catch (MalformedURLException e) {;} } TN.currentDirectory.bIsDirType = true; System.out.println("inputdir: " + getParameter("cavedir")); System.out.println("currentdir: " + TN.currentDirectory.localurl); // MainOpen(true, true, SvxFileDialog.FT_DIRECTORY); LoadTunnelDirectoryTree("cavecave", TN.currentDirectory); MainRefresh(); bFileLoaded = true; } ///////////////////////////////////////////// public void stop() { } ///////////////////////////////////////////// public void destroy() { } ///////////////////////////////////////////// public String getAppletInfo() { return "tunnelx applet. Protected by the GPL"; } } tunnelx-20140102.orig/src/ConnectiveAreaSigTabPane.java0000644000000000000000000004125212261213471017510 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2004 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import javax.swing.JComboBox; import javax.swing.JPanel; import javax.swing.JButton; import javax.swing.BoxLayout; import javax.swing.JCheckBox; import javax.swing.JToggleButton; import javax.swing.JTextField; import javax.swing.JTextArea; import javax.swing.JLabel; import javax.swing.JScrollPane; import java.awt.BorderLayout; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.geom.Rectangle2D; import java.awt.geom.AffineTransform; import java.awt.Insets; import java.util.Map; import java.io.IOException; ///////////////////////////////////////////// class ConnectiveAreaSigTabPane extends JPanel { JComboBox areasignals = new JComboBox(); SketchLineStyle sketchlinestyle; JButton jbcancel = new JButton("Cancel Area-signal"); // we can choose to print just one view on one sheet of paper JButton tfmaxbutt = new JButton("Max"); JButton tfcentrebutt = new JButton("Centr"); JButton tfsketchcopybutt = new JButton("Sketch"); JButton tfimagecopybutt = new JButton("Image"); JButton tfsubstylecopybutt = new JButton("Style"); JButton tfsubmappingcopybutt = new JButton("Copy"); JButton tfsubmappingpastebutt = new JButton("Paste"); JButton tfsetsubsetlower = new JButton("S-lo"); JButton tfsetsubsetupper = new JButton("S-up"); JButton tfshiftground = new JButton("-"); JTextArea tfsubmapping = new JTextArea(); JScrollPane jsp = new JScrollPane(tfsubmapping); // this is used to modify the treeview which we see // it's a bad hidden modal thing, but for now till we think of something better. SketchFrameDef sketchframedefCopied = new SketchFrameDef(); // use these for parsing the text in the submapping textarea TunnelXMLparse txp = new TunnelXMLparse(); TunnelXML tunnXML = new TunnelXML(); String copiedsubmapping = ""; ///////////////////////////////////////////// boolean SketchCopyButt() { // ultimately this should use the same algorithm for finding the sketch name as we do for raw images OneSketch asketch = sketchlinestyle.sketchdisplay.mainbox.tunnelfilelist.GetSelectedSketchLoad(); if (asketch == null) return TN.emitWarning("No sketch found"); String st = null; try { st = FileAbstraction.GetImageFileName(sketchlinestyle.sketchdisplay.sketchgraphicspanel.tsketch.sketchfile.getParentFile(), asketch.sketchfile); } catch (IOException ie) { return TN.emitWarning(ie.toString()); }; if (st == null) return TN.emitWarning("No file found to be recorded (maybe you need to save it)"); st = TN.loseSuffix(st); OnePath op = sketchlinestyle.sketchdisplay.sketchgraphicspanel.currgenpath; if (st != null) op.plabedl.sketchframedef.sfsketch = st; else return TN.emitWarning("No file found to be recorded (maybe you need to save it)"); sketchlinestyle.pthstyleareasigtab.LoadSketchFrameDef(op.plabedl.sketchframedef, true); sketchlinestyle.sketchdisplay.sketchgraphicspanel.tsketch.opframebackgrounddrag = op; PtrelLn ptrelln = new PtrelLn(); boolean bcorrespsucc = ptrelln.ExtractCentrelinePathCorrespondence(asketch, sketchlinestyle.sketchdisplay.sketchgraphicspanel.tsketch); if (bcorrespsucc) { TN.emitMessage("Correspondence found -- repositioning"); AffineTransform avgtrans = new AffineTransform(); ptrelln.CalcAvgTransform(avgtrans, op.plabedl.sketchframedef, sketchlinestyle.sketchdisplay.sketchgraphicspanel.tsketch, asketch); } UpdateSFView(op, true); return true; } ///////////////////////////////////////////// void StyleCopyButt() { SubsetAttrStyle sascurrent = sketchlinestyle.sketchdisplay.subsetpanel.sascurrent; OnePath op = sketchlinestyle.sketchdisplay.sketchgraphicspanel.currgenpath; op.plabedl.sketchframedef.sfstyle = sascurrent.stylename; UpdateSFView(op, true); } ///////////////////////////////////////////// void UpdateSFView(OnePath op, boolean bsketchchanged) { tfsubmapping.setText(op.plabedl.sketchframedef.GetToTextV()); tfsubmapping.setCaretPosition(0); op.SetSubsetAttrs(sketchlinestyle.sketchdisplay.subsetpanel.sascurrent, null); // font changes op.plabedl.sketchframedef.SetSketchFrameFiller(sketchlinestyle.sketchdisplay.mainbox, sketchlinestyle.sketchdisplay.sketchgraphicspanel.tsketch.realposterpaperscale, sketchlinestyle.sketchdisplay.sketchgraphicspanel.tsketch.sketchLocOffset, sketchlinestyle.sketchdisplay.sketchgraphicspanel.tsketch.sketchfile); sketchlinestyle.sketchdisplay.sketchgraphicspanel.RedoBackgroundView(); if (bsketchchanged) sketchlinestyle.sketchdisplay.sketchgraphicspanel.SketchChanged(bsketchchanged ? SketchGraphics.SC_CHANGE_STRUCTURE : SketchGraphics.SC_CHANGE_SAS); } ///////////////////////////////////////////// void LoadSketchFrameDef(SketchFrameDef lsketchframedefCopied, boolean bAll) { sketchframedefCopied.Copy(lsketchframedefCopied, bAll); sketchlinestyle.sketchdisplay.subsetpanel.SubsetSelectionChanged(true); //sketchlinestyle.sketchdisplay.subsetpanel.sascurrent.TreeListFrameDefCopiedSubsets(sketchframedefCopied); //sketchlinestyle.sketchdisplay.sketchgraphicspanel.SketchChanged(SketchGraphics.SC_CHANGE_SAS); } ///////////////////////////////////////////// void StyleMappingCopyButt(boolean bcopypaste) { OnePath op = sketchlinestyle.sketchdisplay.sketchgraphicspanel.currgenpath; if ((op == null) || (op.linestyle != SketchLineStyle.SLS_CONNECTIVE) || (op.plabedl == null) || (op.plabedl.barea_pres_signal != SketchLineStyle.ASE_SKETCHFRAME) || (op.plabedl.sketchframedef == null)) { TN.emitWarning("Can't execute StyleMappingCopyButt"); return; } txp.sketchframedef.submapping.clear(); if (bcopypaste) { copiedsubmapping = tfsubmapping.getText(); tfsubmappingpastebutt.setToolTipText(copiedsubmapping); } String erm = tunnXML.ParseString(txp, (bcopypaste ? tfsubmapping.getText() : copiedsubmapping)); // if successful, copy it into the path and then back if (erm == null) { op.plabedl.sketchframedef.Copy(txp.sketchframedef, true); UpdateSFView(op, !bcopypaste); if (bcopypaste) LoadSketchFrameDef(op.plabedl.sketchframedef, true); } else TN.emitWarning("Failed to parse: " + erm); sketchlinestyle.sketchdisplay.sketchgraphicspanel.tsketch.opframebackgrounddrag = op; if (!bcopypaste) { if (op.plabedl.sketchframedef.IsImageType()) sketchlinestyle.sketchdisplay.sketchgraphicspanel.FrameBackgroundOutline(); } if (sketchlinestyle.sketchdisplay.bottabbedpane.getSelectedIndex() == 1) sketchlinestyle.sketchdisplay.backgroundpanel.UpdateBackimageCombobox(3); } ///////////////////////////////////////////// void MaxCentreOnScreenButtB(boolean bmaxcen) { // find the area which this line corresponds to. (have to search the areas to find it). OnePath op = sketchlinestyle.sketchdisplay.sketchgraphicspanel.currgenpath; if ((op == null) || (op.plabedl == null) || (op.plabedl.sketchframedef == null)) return; sketchlinestyle.sketchdisplay.sketchgraphicspanel.ClearSelection(false); sketchlinestyle.sketchdisplay.sketchgraphicspanel.repaint(); op.plabedl.sketchframedef.MaxCentreOnScreenButt(sketchlinestyle.sketchdisplay.sketchgraphicspanel.getSize(), bmaxcen, sketchlinestyle.sketchdisplay.sketchgraphicspanel.tsketch.realposterpaperscale, sketchlinestyle.sketchdisplay.sketchgraphicspanel.tsketch.sketchLocOffset, sketchlinestyle.sketchdisplay.sketchgraphicspanel.currtrans); sketchlinestyle.sketchdisplay.sketchgraphicspanel.tsketch.opframebackgrounddrag = op; if (op.plabedl.sketchframedef.IsImageType()) sketchlinestyle.sketchdisplay.sketchgraphicspanel.FrameBackgroundOutline(); UpdateSFView(op, true); } ///////////////////////////////////////////// ConnectiveAreaSigTabPane(SketchLineStyle lsketchlinestyle) { super(new BorderLayout()); sketchlinestyle = lsketchlinestyle; txp.sketchframedef = new SketchFrameDef(); JPanel ntop = new JPanel(new BorderLayout()); ntop.add(new JLabel("Area Signals", JLabel.CENTER), BorderLayout.NORTH); JPanel pie = new JPanel(); pie.add(areasignals); pie.add(jbcancel); ntop.add(pie, BorderLayout.CENTER); JPanel pimpfields = new JPanel(new GridLayout(0, 5)); pimpfields.add(tfmaxbutt); pimpfields.add(tfcentrebutt); pimpfields.add(tfshiftground); pimpfields.add(tfsketchcopybutt); pimpfields.add(tfimagecopybutt); pimpfields.add(tfsubstylecopybutt); pimpfields.add(tfsubmappingcopybutt); pimpfields.add(tfsubmappingpastebutt); pimpfields.add(tfsetsubsetlower); pimpfields.add(tfsetsubsetupper); ntop.add(pimpfields, BorderLayout.SOUTH); add(ntop, BorderLayout.NORTH); add(jsp, BorderLayout.CENTER); tfmaxbutt.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { MaxCentreOnScreenButtB(true); } } ); tfcentrebutt.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { MaxCentreOnScreenButtB(false); } } ); tfsketchcopybutt.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { SketchCopyButt(); } } ); tfsubstylecopybutt.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { StyleCopyButt(); } } ); tfimagecopybutt.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { AddImage(); } } ); tfsubmappingcopybutt.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { StyleMappingCopyButt(true); } } ); tfsubmappingpastebutt.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { StyleMappingCopyButt(false); } } ); tfsetsubsetlower.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { SetSubsetLoHi(true); } } ); tfsetsubsetupper.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { SetSubsetLoHi(false); } } ); Insets smallbuttinsets = new Insets(2, 3, 2, 3); tfmaxbutt.setToolTipText("Maximize viewed sketch in framed area"); tfmaxbutt.setMargin(smallbuttinsets); tfcentrebutt.setToolTipText("Centre viewed sketch in framed area"); tfcentrebutt.setMargin(smallbuttinsets); tfsketchcopybutt.setToolTipText("Copy selected sketch from mainbox to framed area"); tfsketchcopybutt.setMargin(smallbuttinsets); tfsubstylecopybutt.setToolTipText("Copy selected style to apply to framed sketch"); tfsubstylecopybutt.setMargin(smallbuttinsets); tfimagecopybutt.setToolTipText("Load image as framed sketch or background"); tfimagecopybutt.setMargin(smallbuttinsets); tfsubmappingcopybutt.setToolTipText("Copy selected style to apply to framed sketch"); tfsubmappingcopybutt.setMargin(smallbuttinsets); tfsubmappingpastebutt.setToolTipText("Paste copied parameters into framed sketch"); tfsubmappingpastebutt.setMargin(smallbuttinsets); tfsetsubsetlower.setToolTipText("Select subset style for assignment"); tfsetsubsetlower.setMargin(smallbuttinsets); tfsetsubsetupper.setToolTipText("Assign upper subset for style"); tfsetsubsetupper.setMargin(smallbuttinsets); } ///////////////////////////////////////////// void SetSubmappingSettings() { OnePath op = sketchlinestyle.sketchdisplay.sketchgraphicspanel.currgenpath; if ((op == null) || (op.plabedl == null) || (op.plabedl.sketchframedef == null)) return; Map submapping = op.plabedl.sketchframedef.submapping; for (String ssubset : submapping.keySet()) { if (submapping.get(ssubset).equals("")) { tfsetsubsetupper.setEnabled(true); return; } } tfsetsubsetupper.setEnabled(false); } ///////////////////////////////////////////// void SetSubsetLoHi(boolean bsetsubsetlohi) { OnePath op = sketchlinestyle.sketchdisplay.sketchgraphicspanel.currgenpath; Map submapping = op.plabedl.sketchframedef.submapping; if (bsetsubsetlohi) { if (sketchlinestyle.sketchdisplay.selectedsubsetstruct.vsselectedsubsetsP.isEmpty()) { if (submapping.containsKey("default")) submapping.put("Your subset here", ""); else submapping.put("default", ""); } else { for (String ssubset : sketchlinestyle.sketchdisplay.selectedsubsetstruct.vsselectedsubsetsP) submapping.put(ssubset, ""); } } else { String ssubsetupper = sketchlinestyle.sketchdisplay.selectedsubsetstruct.GetFirstSubset(); if (ssubsetupper != null) { for (String ssubset : submapping.keySet()) { if (submapping.get(ssubset).equals("")) submapping.put(ssubset, ssubsetupper); } } } SetSubmappingSettings(); UpdateSFView(op, true); } ///////////////////////////////////////////// void UpdateAreaSignals(String[] areasignames, int nareasignames) { areasignals.removeAllItems(); for (int i = 0; i < nareasignames; i++) areasignals.addItem(areasignames[i]); } ///////////////////////////////////////////// void SetFrameSketchInfoText(OnePath op) { boolean bbuttenabled = false; boolean bareaenabled = false; if ((op != null) && (op.plabedl.barea_pres_signal == SketchLineStyle.ASE_SKETCHFRAME)) { if (op.plabedl.sketchframedef == null) op.plabedl.sketchframedef = new SketchFrameDef(); tfsubmapping.setText(op.plabedl.sketchframedef.GetToTextV()); tfsubmapping.setCaretPosition(0); bbuttenabled = true; bareaenabled = true; } if ((op != null) && (op.plabedl.barea_pres_signal == SketchLineStyle.ASE_ZSETRELATIVE)) { tfsubmapping.setText(String.valueOf(op.plabedl.nodeconnzsetrelative)); bareaenabled = true; } tfmaxbutt.setEnabled(bbuttenabled); tfcentrebutt.setEnabled(bbuttenabled); tfsketchcopybutt.setEnabled(bbuttenabled); tfsubstylecopybutt.setEnabled(bbuttenabled); tfimagecopybutt.setEnabled(bbuttenabled); tfsubmappingcopybutt.setEnabled(bbuttenabled); tfsubmappingpastebutt.setEnabled(bbuttenabled); tfsetsubsetlower.setEnabled(bbuttenabled); if (bbuttenabled) SetSubmappingSettings(); else tfsetsubsetupper.setEnabled(false); if (!bareaenabled) tfsubmapping.setText(""); // this has fired IllegalStateException: Attempt to mutate in notification, since it's already been set otherwise tfsubmapping.setEnabled(bareaenabled); } ///////////////////////////////////////////// // This function replecates NewBackgroundFile, which creates the path in the first place // in the future this will be adding a sketch too-- void AddImage() { SvxFileDialog sfiledialog = SvxFileDialog.showOpenDialog(TN.currentDirectory, sketchlinestyle.sketchdisplay, SvxFileDialog.FT_BITMAP, false); if ((sfiledialog == null) || (sfiledialog.svxfile == null)) return; FileAbstraction fa = sfiledialog.getSelectedFileA(SvxFileDialog.FT_BITMAP, false); if (fa.localurl == null) TN.currentDirectory = fa; OnePath op = sketchlinestyle.sketchdisplay.sketchgraphicspanel.currgenpath; if ((op.plabedl == null) || (op.plabedl.sketchframedef == null)) return; try { op.plabedl.sketchframedef.sfsketch = FileAbstraction.GetImageFileName(sketchlinestyle.sketchdisplay.sketchgraphicspanel.tsketch.sketchfile.getParentFile(), sfiledialog.svxfile); } catch (IOException ie) { TN.emitWarning(ie.toString()); }; op.plabedl.sketchframedef.sfscaledown = 1.0F; op.plabedl.sketchframedef.sfrotatedeg = 0.0F; op.plabedl.sketchframedef.sfxtrans = (float)(sketchlinestyle.sketchdisplay.sketchgraphicspanel.tsketch.sketchLocOffset.x / TN.CENTRELINE_MAGNIFICATION); op.plabedl.sketchframedef.sfytrans = -(float)(sketchlinestyle.sketchdisplay.sketchgraphicspanel.tsketch.sketchLocOffset.y / TN.CENTRELINE_MAGNIFICATION); UpdateSFView(op, true); MaxCentreOnScreenButtB(true); if (!sketchlinestyle.sketchdisplay.miShowBackground.isSelected()) sketchlinestyle.sketchdisplay.miShowBackground.doClick(); } }; tunnelx-20140102.orig/src/WireAxes.java0000644000000000000000000000744611762432750014472 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.Graphics; import java.awt.Dimension; ///////////////////////////////////////////// class WireAxes { Matrix3D axesmat = new Matrix3D(); int ax0x = 0, ax0y = 0; int axXx = 0, axXy = 0; int axYx = 0, axYy = 0; int axZx = 0, axZy = 0; boolean bXbY = true, bXbZ = true, bYbZ = true; int axScaLy = 0, axScaLyD = 0, axScaLxlo = 0, axScaLxN = 0; float xfac; // records for the paintw case float[] scaleRG = { 0.5F, 1.0F, 5.0F, 10.0F, 50.0F, 100.0F, 500.0F, 1000.0F }; ///////////////////////////////////////////// void ReformAxes(Matrix3D rotmat, Dimension csize, float xoc, float yoc, float lxfac) { xfac = lxfac; axesmat.SetFrom(rotmat); float afac = Math.min(csize.width, csize.height) / 10.0F; axesmat.scale(afac, -afac, afac * 1.3F); float fax0x = xoc / 4.0F; float fax0y = yoc * (7.0F / 4.0F); ax0x = (int)(fax0x + 0.5F); ax0y = (int)(fax0y + 0.5F); axXx = (int)(fax0x + axesmat.xx + 0.5F); axXy = (int)(fax0y + axesmat.yx + 0.5F); axYx = (int)(fax0x + axesmat.xy + 0.5F); axYy = (int)(fax0y + axesmat.yy + 0.5F); axZx = (int)(fax0x + axesmat.xz + 0.5F); axZy = (int)(fax0y + axesmat.yz + 0.5F); bXbY = (axesmat.zx < axesmat.zy); bXbZ = (axesmat.zx < axesmat.zz); bYbZ = (axesmat.zy < axesmat.zz); axScaLy = (int)(yoc * (7.5F / 4.0F) + 0.5F); axScaLyD = (int)(yoc * (0.1F / 4.0F) + 0.5F); axScaLxN = Math.max((int)((2 * afac + 0.5F) / xfac), 1); axScaLxlo = (int)(fax0x - afac + 0.5F); } ///////////////////////////////////////////// void paintW(Graphics g) { if (axesmat.zz < 0.0F) { g.setColor(TN.wfdaxesZ); g.drawLine(ax0x, ax0y, axZx, axZy); } g.setColor(TN.wfdaxesXY); g.drawLine(ax0x, ax0y, axXx, axXy); g.drawLine(ax0x, ax0y, axYx, axYy); if (axesmat.zz >= 0.0F) { g.setColor(TN.wfdaxesZ); g.drawLine(ax0x, ax0y, axZx, axZy); } // draw the scale bars // step up rate (by fixed if too many bits). boolean bTooWide = (axScaLxN > 120); int sbstep = (axScaLxN < 20 ? 1 : (!bTooWide ? 5 : axScaLxN)); int axScaLxNL = (int)(axScaLxN / sbstep) * sbstep; g.setColor(!bTooWide ? TN.wfdaxesZ : TN.wfdaxesXY); g.drawLine(axScaLxlo, axScaLy, axScaLxlo + (int)(axScaLxNL * xfac + 0.5F), axScaLy); // draw the double size ones if ((sbstep <= 5) && (axScaLxNL >= 5)) { g.setColor(TN.wfdaxesXY); for (int sb = 0; sb <= axScaLxNL; sb += 5) { int xi = axScaLxlo + (int)(sb * xfac + 0.5F); g.drawLine(xi, axScaLy - axScaLyD * 2, xi, axScaLy + axScaLyD * 2); } } g.setColor(!bTooWide ? TN.wfdaxesZ : TN.wfdaxesXY); for (int sb = 0; sb <= axScaLxNL; sb += sbstep) { int xi = axScaLxlo + (int)(sb * xfac + 0.5F); g.drawLine(xi, axScaLy - axScaLyD, xi, axScaLy + axScaLyD); } } ///////////////////////////////////////////// ///////////////////////////////////////////// }; tunnelx-20140102.orig/src/OneSSymbol.java0000644000000000000000000001113711762432750014765 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.Graphics2D; import java.util.Random; import java.util.Arrays; import java.lang.StringBuffer; import java.awt.Rectangle; import java.awt.geom.Rectangle2D; import java.awt.geom.Line2D; import java.awt.geom.Point2D; import java.awt.geom.AffineTransform; import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.GeneralPath; import java.awt.geom.Area; import java.awt.BasicStroke; import java.awt.Color; import java.util.List; ///////////////////////////////////////////// class OneSSymbol { // when we have multisumbols, up to the transformed paths, // the info based on the pos of the axis could be shared. // arrays of sketch components. // location definition Line2D paxis; SSymbolBase ssb; OnePath op; // used to access the line width for detail lines for the subset associated to this symbol (by connective path). GeneralPath gpsymps = null; // all multiple symbols and parts thereof are consolidated into this single path int nsmposvalid = 0; // number of symbols whose position is valid for drawing of the multiplicity. // one to do it all for now. static SSymbScratch Tsscratch = new SSymbScratch(); ///////////////////////////////////////////// // used to preview a couple of positions void RefreshSymbol() { nsmposvalid = 0; gpsymps = null; if (ssb.gsym != null) { Tsscratch.InitAxis(this, true, null); // make some provisional positions just to help the display of multiplicity int nic = (((ssb.nmultiplicity != -1) && (ssb.nmultiplicity < 2)) ? ssb.nmultiplicity : 2); for (int ic = 0; ic < nic; ic++) { Tsscratch.BuildAxisTransSetup(this, ic); gpsymps = AppendTransformedCopy(Tsscratch.BuildAxisTransT(1.0F), gpsymps); } } } ///////////////////////////////////////////// GeneralPath AppendTransformedCopy(AffineTransform paxistrans, GeneralPath lgpsymps) // made complex so we can have a threadsafe use { for (OnePath op : ssb.gsym.vpaths) { if ((op.linestyle == SketchLineStyle.SLS_DETAIL) || (op.linestyle == SketchLineStyle.SLS_FILLED)) { GeneralPath gp = (GeneralPath)op.gp.clone(); gp.transform(paxistrans); if (lgpsymps == null) lgpsymps = gp; else lgpsymps.append(gp, false); } } return lgpsymps; } ///////////////////////////////////////////// ///////////////////////////////////////////// // static Color colsymoutline = new Color(1.0F, 0.8F, 0.8F); // static Color colsymactivearea = new Color(1.0F, 0.2F, 1.0F, 0.16F); void paintW(GraphicsAbstraction ga, boolean bActive, boolean bProperSymbolRender) { if (bProperSymbolRender && (nsmposvalid == 0)) return; LineStyleAttr linestyleattr; if (bActive) linestyleattr = (ssb.bFilledType ? SketchLineStyle.fillactivestylesymb : SketchLineStyle.lineactivestylesymb); else if (bProperSymbolRender) linestyleattr = (ssb.bFilledType ? op.subsetattr.linestyleattrs[SketchLineStyle.SLS_FILLED] : op.subsetattr.linestyleattrs[SketchLineStyle.SLS_DETAIL]); else if (nsmposvalid == 0) linestyleattr = (ssb.bFilledType ? SketchLineStyle.fillstylesymbinvalid : SketchLineStyle.linestylesymbinvalid); else linestyleattr = (ssb.bFilledType ? SketchLineStyle.fillstylesymb : SketchLineStyle.linestylesymb); ga.drawSymbol(this, linestyleattr); } ///////////////////////////////////////////// OneSSymbol() { } ///////////////////////////////////////////// OneSSymbol(float[] pco, int nlines, float zalt, SSymbolBase lssb, OnePath lop) { ssb = lssb; op = lop; // paxis = new Line2D.Float(pco[0], pco[1], pco[nlines * 2], pco[nlines * 2 + 1]); paxis = new Line2D.Float(pco[nlines * 2 - 2], pco[nlines * 2 - 1], pco[nlines * 2], pco[nlines * 2 + 1]); RefreshSymbol(); } } tunnelx-20140102.orig/src/WireframeDisplay.java0000644000000000000000000001430611762432750016203 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JCheckBoxMenuItem; import java.awt.Graphics; import java.awt.FileDialog; import java.awt.BorderLayout; import java.io.IOException; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.WindowEvent; import java.awt.event.WindowAdapter; import javax.swing.JSlider; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; // // // WireframeDisplay // // // this class contains the whole outer set of options and buttons class WireframeDisplay extends JFrame { // the panel which holds the wireframe 3D graphics WireframeGraphics wiregraphicspanel; DateSliderControl dateslidercontrol; boolean[] bmiStationNamesState = new boolean[2]; JCheckBoxMenuItem miCentreline = new JCheckBoxMenuItem("Centreline", true); JCheckBoxMenuItem miStationNames = new JCheckBoxMenuItem("StationNames", true); JCheckBoxMenuItem miAxes = new JCheckBoxMenuItem("Axes", true); JCheckBoxMenuItem miDepthCols = new JCheckBoxMenuItem("Depth Colours", true); JCheckBoxMenuItem miZFixed = new JCheckBoxMenuItem("Z Fixed", true); ///////////////////////////////////////////// // local classes ///////////////////////////////////////////// class AutoViewMenuItem extends JMenuItem implements ActionListener { float zfRotX, zfRotZ; AutoViewMenuItem(String label, float lzfRotX, float lzfRotZ) { super(label); zfRotX = lzfRotX; zfRotZ = lzfRotZ; addActionListener(this); } public void actionPerformed(ActionEvent e) { wiregraphicspanel.SetAutomaticView(zfRotX, zfRotZ); } }; ///////////////////////////////////////////// ItemListener WireframeRepaint = new ItemListener() { public void itemStateChanged(ItemEvent e) { wiregraphicspanel.repaint(); } }; ///////////////////////////////////////////// // inactivate case class WireframeHide extends WindowAdapter implements ActionListener { public void windowClosing(WindowEvent e) { bmiStationNamesState[wiregraphicspanel.bEditable ? 0 : 1] = miStationNames.isSelected(); setVisible(false); } public void actionPerformed(ActionEvent e) { bmiStationNamesState[wiregraphicspanel.bEditable ? 0 : 1] = miStationNames.isSelected(); setVisible(false); } } ///////////////////////////////////////////// // slider on bottom for the amount of cave up to a date class DateSliderControl extends JSlider implements ChangeListener { WireframeGraphics wiregraphicspanel; DateSliderControl(WireframeGraphics lwiregraphicspanel) { super(0, 100, 100); wiregraphicspanel = lwiregraphicspanel; addChangeListener(this); } public void stateChanged(ChangeEvent e) { int slv = getValue(); wiregraphicspanel.depthcol.SetDateLimit(slv / 100.0); wiregraphicspanel.repaint(); } } ///////////////////////////////////////////// // set up the arrays WireframeDisplay() { super("Wireframe Display"); wiregraphicspanel = new WireframeGraphics(this); dateslidercontrol = new DateSliderControl(wiregraphicspanel); // set up display getContentPane().add(wiregraphicspanel, BorderLayout.CENTER); getContentPane().add(dateslidercontrol, BorderLayout.SOUTH); // setup the display menu responses miCentreline.addItemListener(WireframeRepaint); miStationNames.addItemListener(WireframeRepaint); miAxes.addItemListener(WireframeRepaint); miDepthCols.addItemListener(WireframeRepaint); miZFixed.addItemListener(WireframeRepaint); // build the layout of the menu bar JMenuBar menubar = new JMenuBar(); JMenu menufile = new JMenu("File"); JMenuItem doneitem = new JMenuItem("Close"); doneitem.addActionListener(new WireframeHide()); addWindowListener(new WireframeHide()); menufile.add(doneitem); menubar.add(menufile); JMenu menuview = new JMenu("View"); menuview.add(miZFixed); menuview.add(new AutoViewMenuItem("DownZ", (float)Math.PI / 2, (float)Math.PI / 2)); menuview.add(new AutoViewMenuItem("DownX", (float)Math.PI / 4, (float)Math.PI / 4)); menuview.add(new AutoViewMenuItem("DownY", (float)Math.PI * 3 / 4, (float)Math.PI / 4)); menuview.add(new AutoViewMenuItem("Max", -1.0F, -1.0F)); menubar.add(menuview); JMenu menudisplay = new JMenu("Display"); menudisplay.add(miCentreline); menudisplay.add(miStationNames); menudisplay.add(miAxes); menudisplay.add(miDepthCols); menubar.add(menudisplay); setJMenuBar(menubar); bmiStationNamesState[0] = true; bmiStationNamesState[1] = false; pack(); setSize(400, 400); } ///////////////////////////////////////////// void ActivateWireframeDisplay(String lname) { miStationNames.setSelected(bmiStationNamesState[wiregraphicspanel.bEditable ? 0 : 1]); setTitle(lname); toFront(); wiregraphicspanel.ReformMatrix(); wiregraphicspanel.MaximizeView(); wiregraphicspanel.ReformView(); wiregraphicspanel.UpdateDepthCol(); setVisible(true); } ///////////////////////////////////////////// void RefreshWireDisplay() { if (isVisible()) { wiregraphicspanel.ReformView(); wiregraphicspanel.repaint(); } } } tunnelx-20140102.orig/src/TunnelXMLparsebase.java0000644000000000000000000000660211762432750016450 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // FoUndation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; class TunnelXMLparsebase { String[] attnamestack = new String[50]; String[] attvalstack = new String[50]; String[] elemstack = new String[20]; int[] iposstack = new int[20]; int istack = 0; ///////////////////////////////////////////// String SeStack(String name) { for (int i = (istack != 0 ? iposstack[istack - 1] : 0) - 1; i >= 0; i--) { if (attnamestack[i].equals(name)) return attvalstack[i]; } return null; } ///////////////////////////////////////////// String SeStack(String name, String defalt) { String res = SeStack(name); return (res == null ? defalt : res); } ///////////////////////////////////////////// double DeStack(String name) { String snumber = SeStack(name); if (snumber == null) throw new RuntimeException("no number with attribute name: " + name); return Double.parseDouble(snumber); } ///////////////////////////////////////////// double DeStack(String name, double defalt) { String snumber = SeStack(name); if (snumber == null) return defalt; return Double.parseDouble(snumber); } ///////////////////////////////////////////// int IeStack(String name) { String snumber = SeStack(name); if (snumber == null) throw new RuntimeException("no number with attribute name: " + name); return Integer.parseInt(snumber); } ///////////////////////////////////////////// int IeStack(String name, int defalt) { String snumber = SeStack(name); if (snumber == null) return defalt; return Integer.parseInt(snumber); } ///////////////////////////////////////////// boolean ElStack(String name) { for (int i = istack - 1; i >= 0; i--) { if (elemstack[i].equals(name)) return true; } return false; } ///////////////////////////////////////////// void StackDump() { for (int i = istack - 1; i >= 0; i--) { System.out.print("stackdump-- " + elemstack[i] + ":"); for (int j = (i != 0 ? iposstack[i - 1] : 0); j < iposstack[i]; j++) System.out.print(" " + attnamestack[j] + "=" + attvalstack[j]); System.out.println(""); } } ///////////////////////////////////////////// public void startElementAttributesHandled(String name, boolean binlineclose) { } ///////////////////////////////////////////// public void characters(String pstr) { } ///////////////////////////////////////////// public void endElementAttributesHandled(String name) { } ///////////////////////////////////////////// void SetUpBase() { istack = 0; } }; tunnelx-20140102.orig/src/PtrelLn.java0000644000000000000000000004746512261213471014320 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; import java.awt.geom.Line2D; import java.util.List; import java.util.ArrayList; import java.util.Map; import java.util.HashMap; import java.util.Set; import java.util.HashSet; // // // // // ///////////////////////////////////////////// // point relative to line ///////////////////////////////////////////// class PtrelSLn { Line2D.Double axis; double vax, vay; // vector double lgsq, lg; // length. double lam0, lam1; // vector displaced endpoints of the axis. double pvax, pvay; // perp vector double pad; // perp axis displacement. PtrelSLn(Line2D.Double laxis) { axis = laxis; vax = axis.getX2() - axis.getX1(); vay = axis.getY2() - axis.getY1(); lgsq = vax * vax + vay * vay; //check for point1 being the same as point2 else get divide by zero errors. //functions calling this should also check if(lgsq != 0) { lg = Math.sqrt(lgsq); lam0 = (vax * axis.getX1() + vay * axis.getY1()) / lgsq; lam1 = (vax * axis.getX2() + vay * axis.getY2()) / lgsq; pvax = -vay; pvay = vax; pad = (pvax * axis.getX1() + pvay * axis.getY1()) / lgsq; } } }; ///////////////////////////////////////////// // by pairs class PtrelPLn { OnePath cp; OnePath crp; PtrelSLn ax0; PtrelSLn ax1; // mutable values double destx; double desty; double geoweight; // additional weighting derived from the position of the point to line line double disttoaxis; // proxdistance weights at the end pathnodes of a path double proxdistw0; double proxdistw1; ///////////////////////////////////////////// PtrelPLn(OnePath lcp, OnePath lcrp) { cp = lcp; crp = lcrp; } ///////////////////////////////////////////// void MakePtlAxes() { Line2D.Double lax0 = new Line2D.Double(cp.pnstart.pn, cp.pnend.pn); Line2D.Double lax1 = new Line2D.Double(crp.pnstart.pn, crp.pnend.pn); ax0 = new PtrelSLn(lax0); ax1 = new PtrelSLn(lax1); } ///////////////////////////////////////////// // calculates a weighting according to how on the face we are // this weight by orientation doesn't seem to help much, and in fact stops things on corners being pulled along enough double CalcGeoWeightFacing(double lam, double pd) { // distance of point from the ax0 line. double c = Math.abs(pd - ax0.pad) * ax0.lg; // distance of point along the ax0 line from closest point. double a = (lam - ax0.lam0) * ax0.lg; double b = (lam - ax0.lam1) * ax0.lg; double lgeoweight = 10000; if (c > 0.0001) lgeoweight = Math.abs(Math.atan(b / c) - Math.atan(a / c)) / c; else if ((Math.abs(a) > 0.0001) && (Math.abs(b) > 0.0001) && ((a < 0) == (b < 0))) lgeoweight = Math.abs(1 / a - 1 / b); if (lgeoweight > 10000) lgeoweight = 10000; return lgeoweight; } ///////////////////////////////////////////// double CalcGeoWeightDistanceSQ(double lam, double pd) { // distance of point from the ax0 line. double c = Math.abs(pd - ax0.pad) * ax0.lg; disttoaxis = c; // distance of point along the ax0 line from closest point. double d = 0.0; if (lam < ax0.lam0) d = (ax0.lam0 - lam) * ax0.lg; else if (lam > ax0.lam1) d = (lam - ax0.lam1) * ax0.lg; double lgeoweight = c * c + d * d; return ax0.lg / (10.0 + lgeoweight); } ///////////////////////////////////////////// void TransformPt(double x, double y) { //check for either ax0 or ax1 lines having zero length else get divide by zero errors. if ((ax0.lgsq!=0) && (ax1.lgsq!=0)) { double lam = (ax0.vax * x + ax0.vay * y) / ax0.lgsq; double pd = (ax0.pvax * x + ax0.pvay * y) / ax0.lgsq; // calculate the geoweight. // geoweight = CalcGeoWeightFacing(lam, pd); // this one not so good for it geoweight = CalcGeoWeightDistanceSQ(lam, pd); // find the destination point double dlam = lam - ax0.lam0 + ax1.lam0; // factor out changes in width (same idea independently thought out from Walls) double wdfac = ax0.lg / ax1.lg; double dpd = (pd - ax0.pad) * wdfac + ax1.pad; destx = dlam * ax1.vax + dpd * ax1.pvax; desty = dlam * ax1.vay + dpd * ax1.pvay; } //if ax0 or ax1 are zero length set weight to zero so contribution ignored else { destx = 0; desty = 0; geoweight = 0; } } }; ///////////////////////////////////////////// // there's a proximity engine, and this class balances out the // weights of all the proximities to discover the warping class PtrelLn { // corresponding arrays of path nodes. Map opnMap = new HashMap(); List wptrel = new ArrayList(); double destx; double desty; double destz; ProximityDerivation pd = null; Set cenconnnodes = new HashSet(); // set of nodes connected to the centreline AffineTransform ucavgtrans = new AffineTransform(); // applied to the unconnected pieces double realposterpaperscale; Vec3 sketchLocOffsetFrom; Vec3 sketchLocOffsetTo; ///////////////////////////////////////////// PtrelLn() {;} ///////////////////////////////////////////// void PrepareProximity(OneSketch isketch) { pd = new ProximityDerivation(isketch); pd.parainstancequeue.bDropdownConnectiveTraversed = true; pd.parainstancequeue.bCentrelineTraversed = true; pd.parainstancequeue.fcenlinelengthfactor = 10.0F; // factor of length added to centreline connections (to deal with vertical line cases) //clpaths = lclpaths; // extract correspondences between the nodes of the endpoints. // as well as the corresponding distortions. opnMap.clear(); for (PtrelPLn wptreli : wptrel) { wptreli.MakePtlAxes(); opnMap.put(wptreli.cp.pnstart, wptreli.crp.pnstart); opnMap.put(wptreli.cp.pnend, wptreli.crp.pnend); } } ///////////////////////////////////////////// void PrepareForUnconnectedNodes(List vnodes) { // find the centreline nodes; reset the proxdists RefPathO srefpathconn = new RefPathO(); // reused object List lcenconnnodes = new ArrayList(); for (OnePathNode opn : vnodes) { if (opn.IsCentrelineNode()) { cenconnnodes.add(opn); lcenconnnodes.add(opn); } } assert pd.ncentrelinenodes == cenconnnodes.size(); while (!lcenconnnodes.isEmpty()) { OnePathNode copn = lcenconnnodes.remove(lcenconnnodes.size() - 1); srefpathconn.ccopy(copn.ropconn); do { OnePath cop = srefpathconn.op; assert copn == srefpathconn.ToNode(); OnePathNode ocopn = srefpathconn.FromNode(); if (!cenconnnodes.contains(ocopn)) { cenconnnodes.add(ocopn); lcenconnnodes.add(ocopn); } } while (!srefpathconn.AdvanceRoundToNode(copn.ropconn)); } TN.emitMessage("There are " + pd.ncentrelinenodes + " centreline nodes and " + cenconnnodes.size() + " centreline connected nodes out of " + vnodes.size() + " nodes."); } ///////////////////////////////////////////// boolean WarpOver(double x, double y, double z, float lam) { if (wptrel == null) { destx = x; desty = y; destz = z; return true; } double sweight = 0; double sdestx = 0; double sdesty = 0; double sdestz = 0; for (PtrelPLn wptreli : wptrel) { wptreli.TransformPt(x, y); if (lam > 1.0F) lam = 1.0F; if (lam < 0.0F) lam = 0.0F; double aproxdist = wptreli.proxdistw0 * (1.0 - lam) + wptreli.proxdistw1 * lam; double proxweight = 1.0 / (1.0 + aproxdist * aproxdist); if ((wptreli.proxdistw0 == -1.0) || (wptreli.proxdistw1 == -1.0)) proxweight = 0.0; // we just fiddle for something that might work // (is there a better way to combine these two measures??!) // multiplying them makes a big weight on one make the thing into a big weight // double rweight = (proxweight + wptrel[i].weight) * wptrel[i].ax0.lgsq; // double rweight = (proxweight) * wptrel[i].ax0.lgsq; double rweight = (proxweight) * wptreli.geoweight; //System.out.println(wptrel[i].proxdistw0 + " " + wptrel[i].proxdistw1 + " " + wptrel[i].disttoaxis); // double rweight = wptrel[i].geoweight; sweight += rweight; sdestx += rweight * wptreli.destx; sdesty += rweight * wptreli.desty; sdestz += rweight * z; } if (sweight == 0.0) // bail out if no correspondences { destx = x; desty = y; destz = z; System.out.println("no weight (lack of connection?)"); return false; } destx = sdestx / sweight; desty = sdesty / sweight; destz = sdestz / sweight; return true; } ///////////////////////////////////////////// OnePathNode[] cennodes = null; //new OnePathNode[12]; // limit the number of nodes we average over. (null means no limit) // it seems not to work at all if you restrict the number of centre path nodes it links to. void SetNodeProxWeights(OnePathNode opn, int proxto) { if (wptrel == null) // bail out in no correspondences case return; pd.ShortestPathsToCentrelineNodes(opn, cennodes, null); for (int i = 0; i < wptrel.size(); i++) { OnePath opc = wptrel.get(i).cp; // maybe average does work, though small segments near // a node will get pulled much harder // float nodew = (opc.pnstart.proxdist + opc.pnend.proxdist) / 2; double nodew = (opc.pnstart.proxdist * opc.pnend.proxdist); if ((opc.pnstart.proxdist == -1.0) || (opc.pnend.proxdist == -1.0)) nodew = -1.0; if ((proxto & 1) != 0) wptrel.get(i).proxdistw0 = nodew; if ((proxto & 2) != 0) wptrel.get(i).proxdistw1 = nodew; } // reset for next application for (OnePathNode lopn : pd.parainstancequeue.proxdistsetlist) lopn.proxdist = -1.0; pd.parainstancequeue.proxdistsetlist.clear(); } ///////////////////////////////////////////// void Extendallnodes(List vnodes) { int lastprogress = -1; for (int j = 0; j < vnodes.size(); j++) { OnePathNode opn = vnodes.get(j); if (!cenconnnodes.contains(opn)) { assert !opnMap.containsKey(opn); OnePathNode dopn = new OnePathNode(0.0F, 0.0F, 0.0F); ucavgtrans.transform(opn.pn, dopn.pn); // over-writes the origin position opnMap.put(opn, dopn); TN.emitWarning(" unconn-node " + j); } else if (!opnMap.containsKey(opn)) { SetNodeProxWeights(opn, 3); boolean bD = WarpOver(opn.pn.getX(), opn.pn.getY(), opn.zalt, 0.0F); OnePathNode dopn = new OnePathNode((float)destx, (float)desty, (float)destz); if (!bD) TN.emitWarning(" bad node " + j); opnMap.put(opn, dopn); } int progress = (20*j) / vnodes.size(); if (progress > lastprogress) { lastprogress = progress; TN.emitMessage(Integer.toString(5*progress) + "% complete"); } } } ///////////////////////////////////////////// Point2D.Float spnF = new Point2D.Float(); // used for mapping the avgtransform to Point2D.Float spnT = new Point2D.Float(); // used for mapping the avgtransform to OnePath WarpPathD(OnePath path, String limportfromname) { // Must Also map over all the subsets, if there are any made to avoid XC subsets merging // new endpoint nodes OnePathNode npnstart = opnMap.get(path.pnstart); OnePathNode npnend = opnMap.get(path.pnend); OnePath res = new OnePath(npnstart); float[] pco = path.GetCoords(); assert cenconnnodes.contains(path.pnstart) == cenconnnodes.contains(path.pnend); if (!cenconnnodes.contains(path.pnstart)) { for (int i = 1; i < path.nlines; i++) { spnF.setLocation(pco[i * 2], pco[i * 2 + 1]); ucavgtrans.transform(spnF, spnT); res.LineTo((float)spnT.getX(), (float)spnT.getY()); } } else { SetNodeProxWeights(path.pnstart, 1); SetNodeProxWeights(path.pnend, 2); float partlinelength = 0.0F; for (int i = 1; i < path.nlines; i++) { float vx = pco[i * 2] - pco[i * 2 - 2]; float vy = pco[i * 2 + 1] - pco[i * 2 - 1]; partlinelength += (float)Math.sqrt(vx * vx + vy * vy); float lam = partlinelength / path.linelength; WarpOver(pco[i * 2], pco[i * 2 + 1], 0.0F, lam); res.LineTo((float)destx, (float)desty); } } res.EndPath(npnend); res.CopyPathAttributes(path); if ((res.plabedl != null) && (res.plabedl.sketchframedef != null)) res.plabedl.sketchframedef.ConvertTransformImportSketchWarp(path, res, realposterpaperscale, sketchLocOffsetFrom, sketchLocOffsetTo); res.importfromname = limportfromname; return res; } ///////////////////////////////////////////// void CalcAvgTransform(AffineTransform avgtrans, SketchFrameDef sketchframedef, OneSketch tsketch, OneSketch asketch) { // we're working on the diagram as a unit, rather than averaging across the change on all the legs. // so we find the centre of gravity of each. // then average expansion from the c of g. and the rotational components around this, // to the centre of each line weighted by its length. // centre of gravity double cgxf = 0.0F; double cgyf = 0.0F; double tlengf = 0.0F; double cgxt = 0.0F; double cgyt = 0.0F; double tlengt = 0.0F; // first find the centres of gravity. for (PtrelPLn wptreli : wptrel) { OnePath cp = wptreli.cp; OnePath crp = wptreli.crp; double lengf = cp.pnstart.pn.distance(cp.pnend.pn); double lengt = crp.pnstart.pn.distance(crp.pnend.pn); cgxf += lengf * (cp.pnend.pn.getX() + cp.pnstart.pn.getX()) / 2; cgyf += lengf * (cp.pnend.pn.getY() + cp.pnstart.pn.getY()) / 2; tlengf += lengf; cgxt += lengt * (crp.pnend.pn.getX() + crp.pnstart.pn.getX()) / 2; cgyt += lengt * (crp.pnend.pn.getY() + crp.pnstart.pn.getY()) / 2; tlengt += lengt; } if (tlengf != 0.0F) { cgxf /= tlengf; cgyf /= tlengf; } if (tlengt != 0.0F) { cgxt /= tlengt; cgyt /= tlengt; } // now find average scale and rotation relative to these c of g. double tleng = 0.0F; double tscale = 0.0F; double trot = 0.0F; for (PtrelPLn wptreli : wptrel) { OnePath cp = wptreli.cp; OnePath crp = wptreli.crp; double leng = cp.pnstart.pn.distance(cp.pnend.pn); double lengr = crp.pnstart.pn.distance(crp.pnend.pn); double aleng = (leng + lengr) / 2; double cxf = (cp.pnend.pn.getX() + cp.pnstart.pn.getX()) / 2 - cgxf; double cyf = (cp.pnend.pn.getY() + cp.pnstart.pn.getY()) / 2 - cgyf; double cflq = cxf * cxf + cyf * cyf; double cxt = (crp.pnend.pn.getX() + crp.pnstart.pn.getX()) / 2 - cgxt; double cyt = (crp.pnend.pn.getY() + crp.pnstart.pn.getY()) / 2 - cgyt; double ctlq = cxt * cxt + cyt * cyt; tscale += aleng * (cflq != 0.0 ? Math.sqrt(ctlq / cflq) : 1.0); double cxr = cxf * cxt + cyf * cyt; double cyr = cxf * cyt - cyf * cxt; double ang = (cxr != 0 ? Math.atan(cyr / cxr) : 0.0); // alt should be +- PI/2 trot += ang * aleng; tleng += aleng; } if (tleng != 0) { tscale /= tleng; trot /= tleng; } // transform, conijugated with the translation. TN.emitMessage("Avg transform scale " + tscale + " translate " + (cgxt - cgxf) + " " + (cgyt - cgyf) + " rot " + trot); avgtrans.setToIdentity(); avgtrans.translate(cgxt, cgyt); avgtrans.scale(tscale, tscale); avgtrans.rotate(trot); avgtrans.translate(-cgxf, -cgyf); if (sketchframedef != null) { assert (sketchframedef != null) && (tsketch != null); sketchframedef.sfscaledown = (float)(tsketch.realposterpaperscale / tscale); sketchframedef.sfrotatedeg = -(float)Math.toDegrees(trot); sketchframedef.sfelevrotdeg = 0.0F; sketchframedef.sfelevvertplane = ""; // From UpdateSketchFrame() // Lots of effort to extract the transform required AffineTransform lpframesketchtrans = new AffineTransform(); lpframesketchtrans.translate(-tsketch.sketchLocOffset.x * TN.CENTRELINE_MAGNIFICATION, +tsketch.sketchLocOffset.y * TN.CENTRELINE_MAGNIFICATION); lpframesketchtrans.scale(tsketch.realposterpaperscale / sketchframedef.sfscaledown, tsketch.realposterpaperscale / sketchframedef.sfscaledown); lpframesketchtrans.rotate(-Math.toRadians(sketchframedef.sfrotatedeg)); lpframesketchtrans.translate(asketch.sketchLocOffset.x * TN.CENTRELINE_MAGNIFICATION, -asketch.sketchLocOffset.y * TN.CENTRELINE_MAGNIFICATION); double dx = avgtrans.getTranslateX() - lpframesketchtrans.getTranslateX(); double dy = avgtrans.getTranslateY() - lpframesketchtrans.getTranslateY(); sketchframedef.sfxtrans = dx / (tsketch.realposterpaperscale * TN.CENTRELINE_MAGNIFICATION); sketchframedef.sfytrans = dy / (tsketch.realposterpaperscale * TN.CENTRELINE_MAGNIFICATION); /*double[] flatmatrix = new double[6]; avgtrans.getMatrix(flatmatrix); System.out.println("\navgtrans "); for (int i = 0; i < 6; i++) System.out.println(" "+flatmatrix[i]); lpframesketchtrans = new AffineTransform(); lpframesketchtrans.translate((-tsketch.sketchLocOffset.x + sketchframedef.sfxtrans * tsketch.realposterpaperscale) * TN.CENTRELINE_MAGNIFICATION, (+tsketch.sketchLocOffset.y + sketchframedef.sfytrans * tsketch.realposterpaperscale) * TN.CENTRELINE_MAGNIFICATION); lpframesketchtrans.scale(tsketch.realposterpaperscale / sketchframedef.sfscaledown, tsketch.realposterpaperscale / sketchframedef.sfscaledown); lpframesketchtrans.rotate(-Math.toRadians(sketchframedef.sfrotatedeg)); lpframesketchtrans.translate(asketch.sketchLocOffset.x * TN.CENTRELINE_MAGNIFICATION, -asketch.sketchLocOffset.y * TN.CENTRELINE_MAGNIFICATION); lpframesketchtrans.getMatrix(flatmatrix); System.out.println("\n--- lpframesketchtrans "); for (int i = 0; i < 6; i++) System.out.println(" "+flatmatrix[i]); */ // lpframesketchtrans.translate((-tsketch.sketchLocOffset.x + sketchframedef.sfxtrans * tsketch.realpaperscale) * TN.CENTRELINE_MAGNIFICATION, (+tsketch.sketchLocOffset.sketchLocOffset.y + sketchframedef.sfytrans * tsketch.sketchLocOffset.realpaperscale) * TN.CENTRELINE_MAGNIFICATION); } } ///////////////////////////////////////////// ///////////////////////////////////////////// boolean ExtractCentrelinePathCorrespondence(OneSketch asketch, OneSketch osdest) { // new correspondence engine MatchSketchCentrelines msc = new MatchSketchCentrelines(); if (!msc.CorrespMatching(asketch.vpaths, osdest.vpaths)) { TN.emitWarning("no corresponding centrelines found2"); return false; } int nmisscorresp = 0; for (PrefixLeg plf : msc.prefixlegsfrom) { if (plf.pltmember != null) wptrel.add(new PtrelPLn(plf.op, plf.pltmember.op)); else { nmisscorresp++; if (nmisscorresp <= 10) TN.emitWarning("No centreline corresponding to " + "tail=" + plf.op.plabedl.centrelinetail + " head=" + plf.op.plabedl.centrelinehead); } } if (nmisscorresp > 10) TN.emitWarning("No centreline corresponding to ... " + (nmisscorresp - 10) + " more."); // false if no correspondence if (wptrel.isEmpty()) { TN.emitWarning("no corresponding centrelines found1"); return false; } return true; } }; tunnelx-20140102.orig/src/TunnelFileList.java0000644000000000000000000002764312261213471015635 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import javax.swing.JList; import javax.swing.ListModel; import javax.swing.DefaultListModel; import javax.swing.ListSelectionModel; import javax.swing.event.ListSelectionListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.TreeWillExpandListener; import javax.swing.event.TreeExpansionEvent; import java.awt.event.MouseListener; import java.awt.event.MouseEvent; import java.awt.event.MouseAdapter; import javax.swing.JScrollPane; import javax.swing.JPanel; import java.awt.BorderLayout; import javax.swing.JLabel; import javax.swing.ListCellRenderer; import java.awt.Component; import javax.swing.JSplitPane; import java.awt.Dimension; import java.awt.Color; import java.util.List; import java.io.IOException; import javax.swing.JTree; import javax.swing.event.TreeSelectionListener; import javax.swing.event.TreeSelectionEvent; import javax.swing.tree.TreePath; import javax.swing.tree.TreeNode; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.DefaultTreeModel; import javax.swing.JTextArea; // // // // ///////////////////////////////////////////// class DefaultMutableTreeNodeFile extends DefaultMutableTreeNode { FileAbstraction fa = new FileAbstraction(); boolean bdirnodeloaded = false; DefaultMutableTreeNodeFile(FileAbstraction lfa) { super(lfa.getAbsolutePath()); fa = lfa; } public String toString() { return fa.getName() + ((fa.xfiletype == FileAbstraction.FA_DIRECTORY) || (fa.xfiletype == FileAbstraction.FA_FILE_XML_SKETCH) ? "" : " (" + fa.xfiletype + ")"); } public boolean isLeaf() { return (fa.xfiletype != FileAbstraction.FA_DIRECTORY); } } ///////////////////////////////////////////// // this class will encapsulate all the mess that is the left hand side of the mainbox class TunnelFileList extends JPanel implements TreeSelectionListener { MainBox mainbox; JSplitPane jsp; DefaultListModel tflistmodel; JList tflist; final static Color[] colNotLoaded = { new Color(1.0F, 1.0F, 1.0F), new Color(0.7F, 0.8F, 0.9F) }; final static Color[] colLoaded = { new Color(0.8F, 1.0F, 0.8F), new Color(0.2F, 1.0F, 0.3F) }; final static Color[] colNotSaved = { new Color(1.0F, 0.6F, 0.6F), new Color(1.0F, 0.4F, 0.4F) }; final static Color[] colNoFile = { new Color(0.6F, 0.5F, 1.0F), new Color(0.2F, 0.3F, 1.0F) }; // sketch indices int isketche; // last element in list. // what's selected. int activesketchindex; JTree tftree = new JTree(); DefaultMutableTreeNode dmroot = new DefaultMutableTreeNode("root"); DefaultTreeModel dmtreemod = new DefaultTreeModel(dmroot); DefaultMutableTreeNodeFile dmsymbols = new DefaultMutableTreeNodeFile(FileAbstraction.currentSymbols); DefaultMutableTreeNodeFile dmtutorials = new DefaultMutableTreeNodeFile(FileAbstraction.tutorialSketches); ///////////////////////////////////////////// void AddTreeDirectory(FileAbstraction td) { DefaultMutableTreeNodeFile dmtd = new DefaultMutableTreeNodeFile(td); dmroot.add(dmtd); System.out.println("Addtreedirectory " + dmtd.getPath()); dmtreemod.reload(dmroot); LoadDirNode(dmtd); } ///////////////////////////////////////////// synchronized void LoadDirNode(DefaultMutableTreeNodeFile dmtf) { dmtf.bdirnodeloaded = true; // block second loading which can be done in different thread at startup //tunneldirectory.FindFilesOfDirectory(ftsketches, allfontcolours); try { List fod = dmtf.fa.GetDirContents(); for (FileAbstraction tfile : fod) { DefaultMutableTreeNodeFile dmf = new DefaultMutableTreeNodeFile(tfile); dmtf.add(dmf); } dmtreemod.reload(dmtf); } catch (IOException e) { TN.emitWarning(e.toString()); } } ///////////////////////////////////////////// TunnelFileList(MainBox lmainbox) { super(new BorderLayout()); mainbox = lmainbox; tftree.setRootVisible(false); tftree.setShowsRootHandles(true); tftree.setEditable(false); tftree.setExpandsSelectedPaths(true); tftree.addTreeSelectionListener(this); //tftree.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); dmroot.add(dmsymbols); dmroot.add(dmtutorials); tftree.setModel(dmtreemod); tftree.addTreeWillExpandListener(new TreeWillExpandListener() { public void treeWillExpand(TreeExpansionEvent e) { DefaultMutableTreeNodeFile dmtf = (DefaultMutableTreeNodeFile)e.getPath().getLastPathComponent(); if (!dmtf.bdirnodeloaded && (dmtf.fa.xfiletype == FileAbstraction.FA_DIRECTORY)) LoadDirNode(dmtf); } public void treeWillCollapse(TreeExpansionEvent e) {;} }); tftree.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { int selRow = tftree.getRowForLocation(e.getX(), e.getY()); TreePath selPath = tftree.getPathForLocation(e.getX(), e.getY()); if ((selRow == -1) || (e.getClickCount() != 2)) return; DefaultMutableTreeNodeFile dmtf = (DefaultMutableTreeNodeFile)selPath.getLastPathComponent(); //System.out.println(dmtf.fa.getAbsolutePath() + " " + e.getClickCount()); if (mainbox.GetActiveTunnelSketches() == mainbox.vgsymbolstsketches) TN.emitWarning("Cannot use on symbols list"); else if (dmtf.fa.xfiletype == FileAbstraction.FA_FILE_XML_SKETCH) { List ftsketches = mainbox.GetActiveTunnelSketches(); // shouldn't ever work on symbols int iselindex = -1; for (int i = 0; i < ftsketches.size(); i++) { if (dmtf.fa.equals(ftsketches.get(i).sketchfile)) iselindex = i; } // either select it or load it new if (iselindex != -1) { tflist.setSelectedIndex(iselindex); mainbox.ViewSketch(ftsketches.get(iselindex)); } else mainbox.MainOpen(dmtf.fa, SvxFileDialog.FT_XMLSKETCH); } else if (dmtf.fa.xfiletype == FileAbstraction.FA_FILE_SVX) mainbox.MainOpen(dmtf.fa, SvxFileDialog.FT_SVX); else if (dmtf.fa.xfiletype == FileAbstraction.FA_FILE_POCKET_BINTOP) mainbox.MainOpen(dmtf.fa, SvxFileDialog.FT_SVX); else TN.emitWarning("Nothing to do on type " + dmtf.fa.xfiletype + " which is at "+dmtf.fa.getAbsolutePath()); } }); tflistmodel = new DefaultListModel(); tflist = new JList(tflistmodel); tflist.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); tflist.setCellRenderer(new ColourCellRenderer()); tflist.addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { UpdateSelect(false); }; }); tflist.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) UpdateSelect(true); } }); jsp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); jsp.setRightComponent(new JScrollPane(tflist)); jsp.setLeftComponent(new JScrollPane(tftree)); add(jsp, BorderLayout.CENTER); //Create the scroll pane and add the tree to it. //setViewportView(tflist); } ///////////////////////////////////////////// OneSketch GetSelectedSketchLoad() { // load the sketch if necessary. Then import it if (activesketchindex == -1) return null; OneSketch lselectedsketch = mainbox.GetActiveTunnelSketches().get(activesketchindex); if (!lselectedsketch.bsketchfileloaded) { mainbox.tunnelloader.LoadSketchFile(lselectedsketch, true); tflist.repaint(); } return lselectedsketch; } ///////////////////////////////////////////// class ColourCellRenderer extends JLabel implements ListCellRenderer { // This is the only method defined by ListCellRenderer. // We just reconfigure the JLabel each time we're called. public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { assert index != -1; // this is the null setting for the listed indices // one of the strings in the list (the other type files) Color[] colsch; if (value instanceof String) { colsch = colNotLoaded; setText((String)value); } else if (!(index < isketche)) { TN.emitWarning("strange index setting " + index + "<" + isketche + " " + tflistmodel.getSize()); colsch = colNotLoaded; setText(value.toString()); } // sketch type // we have to dereference from the array rather than use the object here since it may have been loaded else { assert (index < isketche); OneSketch rsketch = mainbox.GetActiveTunnelSketches().get(index); FileAbstraction skfile = rsketch.sketchfile; setText((isSelected ? "--" : "") + skfile.getSketchName() + " | " + skfile.getPath()); colsch = (!rsketch.bsketchfileloaded ? colNotLoaded : (rsketch.bsketchfilechanged ? colNotSaved : colLoaded)); } setForeground(isSelected ? list.getSelectionForeground() : list.getForeground()); setBackground(colsch[isSelected ? 1 : 0]); setOpaque(true); return this; } } ///////////////////////////////////////////// public void valueChanged(TreeSelectionEvent e) { //System.out.println("hi there" + e); } ///////////////////////////////////////////// void RemakeTFList() { System.out.println("RemakeTFList with " + mainbox.GetActiveTunnelSketches().size() + " entries"); activesketchindex = -1; // clearing and adding the elements into the list model in a tight loop sometimes failed to give any list at all // on startup of this window. Okay after startup if it changed and this function was called. // Unresolved problem. Not sure how this list fits in with the tree view as well //tflistmodel.clear(); tflistmodel = new DefaultListModel(); for (OneSketch tsketch : mainbox.GetActiveTunnelSketches()) tflistmodel.addElement(tsketch); isketche = tflistmodel.getSize(); System.out.println("isketche " + isketche); tflist.setModel(tflistmodel); } ///////////////////////////////////////////// public void UpdateSelect(boolean bDoubleClick) { // work out what it is that's selected. int index = tflist.getSelectedIndex(); activesketchindex = -1; if (index < isketche) activesketchindex = index; // spawn off the window. if (bDoubleClick) mainbox.ViewSketch((activesketchindex != -1 ? mainbox.GetActiveTunnelSketches().get(activesketchindex) : null)); } } tunnelx-20140102.orig/src/Vec3d.java0000644000000000000000000000356011762432750013700 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2008 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; // // // Vec3d - double version of Vec3 // // class Vec3d { public double x; public double y; public double z; ///////////////////////////////////////////// public Vec3d() { x = 0.0; y = 0.0; z = 0.0; } ///////////////////////////////////////////// public String toString() { return String.valueOf(x) + " " + String.valueOf(y) + " " + String.valueOf(z); } ///////////////////////////////////////////// Vec3d(double lx, double ly, double lz) { x = lx; y = ly; z = lz; } ///////////////////////////////////////////// Vec3d(String w0, String w1, String w2) { x = Double.parseDouble(w0); y = Double.parseDouble(w1); z = Double.parseDouble(w2); } ///////////////////////////////////////////// public void PlusEquals(Vec3d a) { x += a.x; y += a.y; z += a.z; } ///////////////////////////////////////////// public void TimesEquals(double f) { x *= f; y *= f; z *= f; } } tunnelx-20140102.orig/src/OneSketch.java0000644000000000000000000010402512261213471014605 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.Graphics2D; import java.util.Random; import java.util.List; import java.util.ArrayList; import java.util.SortedSet; import java.util.TreeSet; import java.util.Set; import java.util.HashSet; import java.util.Collections; import java.util.Comparator; import java.util.Map; import java.util.TreeMap; import java.util.Collection; import java.io.IOException; import java.awt.Rectangle; import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D.Float; import java.awt.Shape; import java.awt.geom.Area; import java.awt.geom.Point2D; import java.awt.geom.Line2D; import java.awt.geom.AffineTransform; import java.awt.geom.GeneralPath; import java.io.IOException; import java.awt.Color; import java.awt.Image; import javax.swing.JProgressBar; ///////////////////////////////////////////// class OneSketch { // this must always be set FileAbstraction sketchfile = null; boolean bsketchfileloaded = false; String tunnelprojectloaded = ""; String tunneluserloaded = ""; String tunnelversionloaded = ""; String tunneldateloaded = ""; // arrays of sketch components. String sketchsymbolname; // not null if it's a symbol type boolean bSymbolType = false; // tells us which functions are allowed. // this could keep an update of deletes, inserts, and changes in properties (a flag on the path) boolean bsketchfilechanged = false; int isketchchangecount = 0; // increments whenever there is a change. should supercede bsketchfilechanged if used properly // main sketch. List vnodes; List vpaths; // *** this is the only thing saved saved out into XML file OnePath opframebackgrounddrag = null; Vec3 sketchLocOffset; // sets it to zero by default // scaledown when we import background sketches into areas on the poster size (so posters don't have to be many kms wide in real space, and instead at least approx on right scale) double realposterpaperscale = 1.0; // gets reset in ImportPaperM to 1000 if no included background images already in the file Rectangle2D rbounds = null; boolean bZonnodesUpdated = false; boolean bSAreasUpdated = false; boolean bSymbolLayoutUpdated = false; SortedSet vsareas; Set sallsubsets; // this gets the clockwise auto-area. OneSArea cliparea = null; SketchSymbolAreas sksya; // this is a vector of ConnectiveComponents // range and restrictions in the display. boolean bRestrictSubsetCode = false; float zaltlo; float zalthi; SubsetAttrStyle sksascurrent = null; Map submappingcurrent = new TreeMap(); // cache this as well so we can tell when it changes (not well organized) boolean bWallwhiteoutlines = true; // some flag that ought to be passed in static Color colframebackgroundshow = new Color(0.4F, 0.7F, 0.4F, 0.2F); static Color colframebackgroundimageshow = new Color(0.7F, 0.4F, 0.7F, 0.2F); // quick and dirty undo feature used by SketchGraphics.CommitPathChanges List pthstoremoveSaved = null; List pthstoaddSaved = null; ///////////////////////////////////////////// OneSketch(FileAbstraction lsketchfile) { sketchfile = lsketchfile; bsketchfileloaded = false; } ///////////////////////////////////////////// void UpdateSomething(int scchangetyp, boolean bforce) { if (((scchangetyp == SketchGraphics.SC_UPDATE_ZNODES) || (scchangetyp == SketchGraphics.SC_UPDATE_ALL) || (scchangetyp == SketchGraphics.SC_UPDATE_ALL_BUT_SYMBOLS))&& (bforce || !bZonnodesUpdated)) { ProximityDerivation pd = new ProximityDerivation(this); pd.SetZaltsFromCNodesByInverseSquareWeight(this); // passed in for the zaltlo/hi values bZonnodesUpdated = true; } if (((scchangetyp == SketchGraphics.SC_UPDATE_AREAS) || (scchangetyp == SketchGraphics.SC_UPDATE_ALL) || (scchangetyp == SketchGraphics.SC_UPDATE_ALL_BUT_SYMBOLS))&& (bforce || !bSAreasUpdated)) { MakeAutoAreas(); // once it is on always this will be unnecessary. assert OnePathNode.CheckAllPathCounts(vnodes, vpaths); // used to be part of the Update symbols areas, but brought here // so we have a full set of paths associated to each area available // for use to pushing into subsets. MakeConnectiveComponentsT(); for (OneSArea osa : vsareas) osa.SetSubsetAttrsA(true, sksascurrent); bSAreasUpdated = true; } if (((scchangetyp == SketchGraphics.SC_UPDATE_SYMBOLS) || (scchangetyp == SketchGraphics.SC_UPDATE_ALL)) && (bforce || !bSymbolLayoutUpdated)) { MainBox.symbollayoutprocess.UpdateSymbolLayout(sksya.vconncommutual, null); bSymbolLayoutUpdated = true; } } ///////////////////////////////////////////// void SetupSK() { assert !bsketchfileloaded; // main sketch. vnodes = new ArrayList(); vpaths = new ArrayList(); // this is saved out into XML sketchLocOffset = new Vec3(0.0F, 0.0F, 0.0F); // sets it to zero by default vsareas = new TreeSet(); sallsubsets = new HashSet(); sksya = new SketchSymbolAreas(); // this is a vector of ConnectiveComponents bsketchfileloaded = true; } ///////////////////////////////////////////// void ApplySplineChange() { for (OnePath op : vpaths) { if (OnePath.bHideSplines && op.bSplined) op.Spline(false, false); else if (!OnePath.bHideSplines && !op.bSplined && op.bWantSplined) op.Spline(true, false); } } ///////////////////////////////////////////// // the complexity comes when the opfront is also in the list and must be suppressed. OnePathNode SelNode(OnePathNode opfront, boolean bopfrontvalid, Graphics2D g2D, Rectangle selrect, OnePathNode selpathnodecycle, Set tsvnodesviz) { boolean bOvWrite = true; OnePathNode selnode = null; if (bopfrontvalid && g2D.hit(selrect, opfront.Getpnell(), false)) { bOvWrite = (opfront == selpathnodecycle); selnode = opfront; } for (OnePathNode pathnode : tsvnodesviz) { if ((bOvWrite || (pathnode == selpathnodecycle)) && g2D.hit(selrect, pathnode.Getpnell(), false)) { boolean lbOvWrite = bOvWrite; bOvWrite = (pathnode == selpathnodecycle); if (lbOvWrite) selnode = pathnode; } } return selnode; } ///////////////////////////////////////////// OnePath SelPath(Graphics2D g2D, Rectangle selrect, OnePath prevselpath, Collection tsvpathsviz) { boolean bOvWrite = true; OnePath selpath = null; assert selrect != null; for (OnePath path : tsvpathsviz) { assert path.gp != null; if ((bOvWrite || (path == prevselpath)) && (g2D.hit(selrect, path.gp, true) || ((path.plabedl != null) && (path.plabedl.drawlab != null) && (path.plabedl.rectdef != null) && (path.plabedl.labfontattr != null) && (path.plabedl.labfontattr.labelcolour != null) && g2D.hit(selrect, path.plabedl.rectdef, false)))) { boolean lbOvWrite = bOvWrite; bOvWrite = (path == prevselpath); if (lbOvWrite) selpath = path; } } return selpath; } ///////////////////////////////////////////// OneSArea SelArea(Graphics2D g2D, Rectangle selrect, OneSArea prevselarea, SortedSet tsvareasviz) { boolean bOvWrite = true; OneSArea selarea = null; int isel = -1; for (OneSArea oa : tsvareasviz) { if ((bOvWrite || (oa == prevselarea)) && g2D.hit(selrect, oa.gparea, false)) { boolean lbOvWrite = bOvWrite; bOvWrite = (oa == prevselarea); if (lbOvWrite) selarea = oa; } } return selarea; } ///////////////////////////////////////////// OnePath GetAxisPath() { for (OnePath op : vpaths) { if (op.linestyle == SketchLineStyle.SLS_CENTRELINE) return op; } return null; } ///////////////////////////////////////////// void MakeConnectiveComponentsT() { // use new symbol layout engine sksya.MakeSSA(vpaths, vsareas); } ///////////////////////////////////////////// void AddArea(OnePath lop, boolean lbFore, List vsareastakeout) { OneSArea osa = new OneSArea(lop, lbFore); if (osa.gparea == null) // no area (just a tree) { vsareastakeout.add(osa); osa.iareapressig = SketchLineStyle.ASE_NOAREA; return; // no linking created } // iareapressig gets picked up by the iteration around the contour the paths which make up this area // the clockwise path is the one bounding the outside. // it will say how many distinct pieces there are. int aread = OneSArea.FindOrientationReliable(osa.gparea); // can't determin orientation (should set the karight to null) if (aread != 1) // good areas are always clockwise { if (aread == -1) { if (bSymbolType && (cliparea != null)) TN.emitWarning("More than one outerarea for cliparea in symbol " + sketchsymbolname); cliparea = osa; // the outer area thing if not a } osa.iareapressig = SketchLineStyle.ASE_OUTERAREA; vsareastakeout.add(osa); return; } // take out the areas that have been knocked out by area_signals if (osa.iareapressig == SketchLineStyle.ASE_KILLAREA) // rock/tree type (not pitchhole) { vsareastakeout.add(osa); return; } vsareas.add(osa); } ///////////////////////////////////////////// class opcenscomp implements Comparator { public int compare(OnePath op1, OnePath op2) { float zalt1 = Math.max(op1.pnstart.zalt, op1.pnend.zalt); float zalt2 = Math.max(op2.pnstart.zalt, op2.pnend.zalt); return (int)Math.signum(zalt1 - zalt2); } } ///////////////////////////////////////////// void AttachRemainingCentrelines() { List opcens = new ArrayList(); for (OnePath op : vpaths) { if ((op.linestyle == SketchLineStyle.SLS_CENTRELINE) && (op.karight == null) && (op.pnstart != null) && (op.pnend != null)) opcens.add(op); } // get the order right and zip it up with the areas Collections.sort(opcens, new opcenscomp()); int iopcens = 0; OneSArea osaprev = null; for (OneSArea osa : vsareas) { osa.nconnpathremaining = osa.connpathrootscen.size(); while (iopcens < opcens.size()) { OnePath op = opcens.get(iopcens); float pzalt = Math.max(op.pnstart.zalt, op.pnend.zalt); if (pzalt > osa.zalt) break; if (osaprev != null) // centrelines below the lowest area aren't associated with any of them, so get drawn first. osaprev.SetCentrelineThisArea(op, true); iopcens++; } osaprev = osa; } while (iopcens < opcens.size()) // final piece above the last area { OnePath op = opcens.get(iopcens); if (osaprev != null) osaprev.SetCentrelineThisArea(op, true); iopcens++; } } ///////////////////////////////////////////// // fills in the opforeright values etc. // works selectively on a subset of vnodes. void MakeAutoAreas() { assert bsketchfileloaded; // set values to null. esp the area links. for (OnePath op : vpaths) { op.karight = null; op.kaleft = null; } assert OnePathNode.CheckAllPathCounts(vnodes, vpaths); // build the main list which we keep in order for rendering vsareas.clear(); cliparea = null; // now collate the areas. List vsareastakeout = new ArrayList(); for (OnePath op : vpaths) { if (op.AreaBoundingType()) { if (op.karight == null) AddArea(op, true, vsareastakeout); // this constructer makes all the links too. if (op.kaleft == null) AddArea(op, false, vsareastakeout); // this constructer makes all the links too. } } // Now clear out the links in the altareas for (OneSArea osa : vsareastakeout) osa.SetkapointersClear(); if (vsareas.isEmpty()) return; // make the range set of the areas // this is all to do with setting the zaltlam variable double zaaltlo = vsareas.first().zalt; double zaalthi = vsareas.last().zalt; assert zaaltlo <= zaalthi; double zaaltdiff = zaalthi - zaaltlo; if (zaaltdiff == 0.0) zaaltdiff = 1.0; for (OneSArea osa : vsareas) osa.icollam = (float)((osa.zalt - zaaltlo) / zaaltdiff); if (!bSymbolType) AttachRemainingCentrelines(); } ///////////////////////////////////////////// int TAddPath(OnePath path, Collection tsvnodesviz) { assert (path.apforeright == null) && (path.aptailleft == null); if (path.pnstart.pathcount == 0) { assert !vnodes.contains(path.pnstart); path.pnstart.SetNodeCloseBefore(vnodes, vnodes.size()); // makes the start shaped nodes vnodes.add(path.pnstart); if (tsvnodesviz != null) tsvnodesviz.add(path.pnstart); } path.pnstart.InsertOnNode(path, false); if (path.pnend.pathcount == 0) { assert !vnodes.contains(path.pnend); path.pnend.SetNodeCloseBefore(vnodes, vnodes.size()); vnodes.add(path.pnend); if (tsvnodesviz != null) tsvnodesviz.add(path.pnend); } path.pnend.InsertOnNode(path, true); if (path.uuid == null) path.uuid = "p"+String.valueOf((int)(Math.random()*10000000)); vpaths.add(path); assert path.pnstart.CheckPathCount(); assert path.pnend.CheckPathCount(); return vpaths.size() - 1; } ///////////////////////////////////////////// static RefPathO trefpath = new RefPathO(); boolean TRemovePath(OnePath op, SortedSet tsvareasviz, Set tsvnodesviz) { // remove any areas automatically if (op.AreaBoundingType()) { if (op.kaleft != null) { // can be falsified if there's been a change from a wall to a connective type //assert vsareas.contains(op.kaleft); vsareas.remove(op.kaleft); tsvareasviz.remove(op.kaleft); op.kaleft.SetkapointersClear(); } if (op.karight != null) { //assert vsareas.contains(op.karight); vsareas.remove(op.karight); tsvareasviz.remove(op.karight); op.karight.SetkapointersClear(); } } else if ((op.linestyle == SketchLineStyle.SLS_CONNECTIVE) && (op.pthcca != null)) { // assert op.pthcca.vconnpaths.contains(op); // may have already been removed op.pthcca.vconnpaths.remove(op); } trefpath.op = op; trefpath.bFore = false; if (op.pnstart.RemoveOnNode(trefpath)) { vnodes.remove(op.pnstart); tsvnodesviz.remove(op.pnstart); } trefpath.bFore = true; if (op.pnend.RemoveOnNode(trefpath)) { vnodes.remove(op.pnend); tsvnodesviz.remove(op.pnend); } assert (op.pnstart.pathcount == 0) || op.pnstart.CheckPathCount(); assert (op.pnend.pathcount == 0) || op.pnend.CheckPathCount(); return vpaths.remove(op); } ///////////////////////////////////////////// Rectangle2D getBounds(boolean bForce, boolean bOfSubset) { if (!bForce && (rbounds != null) && !bOfSubset) return rbounds; Rectangle2D.Float lrbounds = new Rectangle2D.Float(); boolean bFirst = true; for (OnePath op : vpaths) { if (!bOfSubset || !bRestrictSubsetCode || op.bpathvisiblesubset) { if (bFirst) { lrbounds.setRect(op.getBounds(null)); bFirst = false; } else lrbounds.add(op.getBounds(null)); } } // cache the result if (!bOfSubset) rbounds = lrbounds; return lrbounds; } ///////////////////////////////////////////// void WriteXML(LineOutputStream los) throws IOException { // we default set the sketch condition to unsplined for all edges. los.WriteLine(TNXML.xcomopen(0, TNXML.sSKETCH, TNXML.sSPLINED, "0", TNXML.sSKETCH_LOCOFFSETX, String.valueOf(sketchLocOffset.x), TNXML.sSKETCH_LOCOFFSETY, String.valueOf(sketchLocOffset.y), TNXML.sSKETCH_LOCOFFSETZ, String.valueOf(sketchLocOffset.z), TNXML.sSKETCH_REALPAPERSCALE, String.valueOf(realposterpaperscale))); // write out the paths. // IIII this is where we number the path nodes for (OnePath op : vpaths) { int ind0 = vnodes.indexOf(op.pnstart); int ind1 = vnodes.indexOf(op.pnend); if ((ind0 != -1) && (ind1 != -1)) op.WriteXMLpath(los, ind0, ind1, 1); else TN.emitProgError("Path_node missing end " + vpaths.indexOf(op)); } los.WriteLine(TNXML.xcomclose(0, TNXML.sSKETCH)); } ///////////////////////////////////////////// void SaveSketchLos(LineOutputStream los) throws IOException { los.WriteLine(TNXML.sHEADER); los.WriteLine(""); los.WriteLine(TNXML.xcomopen(0, TNXML.sTUNNELXML, TNXML.sTUNNELVERSION, TN.tunnelversion, TNXML.sTUNNELPROJECT, TN.tunnelproject, TNXML.sTUNNELUSER, TN.tunneluser, TNXML.sTUNNELDATE, TN.tunneldate())); WriteXML(los); los.WriteLine(TNXML.xcomclose(0, TNXML.sTUNNELXML)); } ///////////////////////////////////////////// boolean SaveSketch() { if (!bsketchfileloaded) return TN.emitWarning("Cannot save a file that's not loaded"); // save when it's a download from seagrass if (sketchfile.localurl != null) { FileAbstraction uploadedimage = NetConnection.uploadFile(sketchfile, "sketch", sketchfile.getSketchName() + ".xml", null, this); if (uploadedimage == null) return TN.emitWarning("bum2"); // needs assert that it's the same //sketchgraphicspanel.tsketch.sketchfile = FileAbstraction.GetImageFile(fasketch, TN.setSuffix(uploadedimage.getPath(), TN.SUFF_XML)); bsketchfilechanged = false; return true; } try { LineOutputStream los = new LineOutputStream(sketchfile); SaveSketchLos(los); los.close(); bsketchfilechanged = false; } catch (IOException ie) { TN.emitWarning(ie.toString()); return false; }; return true; } ///////////////////////////////////////////// void pwqWallOutlinesPath(GraphicsAbstraction ga, OnePath op) { if (op.ciHasrendered != 0) return; op.ciHasrendered = 1; if (bRestrictSubsetCode && op.bpathvisiblesubset) return; if ((op.linestyle == SketchLineStyle.SLS_INVISIBLE) || (op.linestyle == SketchLineStyle.SLS_CONNECTIVE)) return; if (op.subsetattr.linestyleattrs[op.linestyle] == null) return; if (op.subsetattr.shadowlinestyleattrs[op.linestyle].linestroke == null) return; ga.drawPath(op, op.subsetattr.shadowlinestyleattrs[op.linestyle]); } ///////////////////////////////////////////// void pwqWallOutlinesArea(GraphicsAbstraction ga, OneSArea osa) { for (RefPathO rpo : osa.refpathsub) { pwqWallOutlinesPath(ga, rpo.op); paintWqualityjoiningpaths(ga, rpo.ToNode(), true); } } ///////////////////////////////////////////// void pwqPathsNonAreaNoLabels(GraphicsAbstraction ga) { // check any paths if they are now done for (OnePath op : vpaths) { op.ciHasrendered = 0; if (op.linestyle == SketchLineStyle.SLS_CONNECTIVE) { op.pnstart.pathcountch++; op.pnend.pathcountch++; op.ciHasrendered = 2; continue; } // path belongs to an area if ((op.karight != null) || (op.kaleft != null)) continue; // no shadows are painted on unarea types op.pnstart.pathcountch++; op.pnend.pathcountch++; op.ciHasrendered = 3; // the rest of the drawing of this path with quality if (!bRestrictSubsetCode || op.bpathvisiblesubset) op.paintWquality(ga); } } ///////////////////////////////////////////// static RefPathO srefpathconn = new RefPathO(); void paintWqualityjoiningpaths(GraphicsAbstraction ga, OnePathNode opn, boolean bShadowpaths) { srefpathconn.ccopy(opn.ropconn); do { OnePath op = srefpathconn.op; if (bShadowpaths) { if (!bRestrictSubsetCode || op.bpathvisiblesubset) pwqWallOutlinesPath(ga, op); } else if ((op.ciHasrendered != 3) && (op.pnstart.pathcountch == op.pnstart.pathcount) && (op.pnend.pathcountch == op.pnend.pathcount)) { if (!bRestrictSubsetCode || op.bpathvisiblesubset) op.paintWquality(ga); op.ciHasrendered = 3; } } while (!srefpathconn.AdvanceRoundToNode(opn.ropconn)); } ///////////////////////////////////////////// void pwqPathsOnAreaNoLabels(GraphicsAbstraction ga, OneSArea osa, Rectangle2D abounds) { // got to do the associated centrelines first for (OnePath op : osa.connpathrootscen) { if (op.linestyle == SketchLineStyle.SLS_CENTRELINE) { assert (op.kaleft == osa) && (op.karight == osa); op.pnstart.pathcountch++; op.pnend.pathcountch++; op.paintWquality(ga); op.ciHasrendered = 3; // if any of these starts and ends trip over the count then we need to do their connections if (bWallwhiteoutlines) { // now embed drawing all the lines connecting to the two end-nodes if (op.pnstart.pathcountch == op.pnstart.pathcount) paintWqualityjoiningpaths(ga, op.pnstart, false); if (op.pnend.pathcountch == op.pnend.pathcount) paintWqualityjoiningpaths(ga, op.pnend, false); } } } // there are duplicates in the refpaths list, so we cannot inline this check for (RefPathO rpo : osa.refpaths) assert (rpo.op.ciHasrendered <= 1); // check any paths if they are now done for (RefPathO rpo : osa.refpaths) { OnePath op = rpo.op; assert ((op.karight == osa) || (op.kaleft == osa)); if (op.ciHasrendered >= 2) continue; if (((op.karight != null) && !op.karight.bHasrendered) || ((op.kaleft != null) && !op.kaleft.bHasrendered)) continue; op.ciHasrendered = 2; op.pnstart.pathcountch++; op.pnend.pathcountch++; assert op.pnstart.pathcountch <= op.pnstart.pathcount; assert op.pnend.pathcountch <= op.pnend.pathcount; if ((abounds != null) && !op.gp.intersects(abounds)) continue; // the rest of the drawing of this path with quality if (bWallwhiteoutlines) { // now embed drawing all the lines connecting to the two end-nodes if (op.pnstart.pathcountch == op.pnstart.pathcount) paintWqualityjoiningpaths(ga, op.pnstart, false); if (op.pnend.pathcountch == op.pnend.pathcount) paintWqualityjoiningpaths(ga, op.pnend, false); } else { if (!bRestrictSubsetCode || op.bpathvisiblesubset) op.paintWquality(ga); op.ciHasrendered = 3; } } } ///////////////////////////////////////////// void pwqSymbolsOnArea(GraphicsAbstraction ga, OneSArea osa) { //ga.setColor(SketchLineStyle.linestylecolprint); // check any symbols that are now done // (there will be only one last area to come through). // once all areas in the connective component have been rendered, the symbols get rendered. // in practice, this is equivalent to the connective component being rendered when the last area in its list gets rendered // after we render an area, the only changes could happen with the connective components that had that area for (ConnectiveComponentAreas mcca : osa.ccalist) { if (!bRestrictSubsetCode || mcca.bccavisiblesubset) { if (!mcca.bHasrendered) { boolean bHasr = false; // basically does an and across values in this list -- might be better with a count for (OneSArea cosa : mcca.vconnareas) { if (!cosa.bHasrendered) { bHasr = true; break; } } if (!bHasr) { mcca.paintWsymbols(ga); mcca.bHasrendered = true; } } } } } ///////////////////////////////////////////// int SetSubsetAttrStyle(SubsetAttrStyle lsksascurrent, SketchFrameDef sketchframedef) { int res = SketchGraphics.SC_CHANGE_SAS_SYMBOLS_SAME; if (sksascurrent != lsksascurrent) res = SketchGraphics.SC_CHANGE_SAS; sksascurrent = lsksascurrent; // check if all the submapping has the same symbols // which is the real work because we have to find equivalence classes of subsets // with the same symbol layout if ((sketchframedef != null) && !submappingcurrent.equals(sketchframedef.submapping)) res = SketchGraphics.SC_CHANGE_SAS; submappingcurrent.clear(); if (sketchframedef != null) { submappingcurrent.putAll(sketchframedef.submapping); sksascurrent.AssignDefault(sketchframedef); } // this sets the values on the paths for (OnePath op : vpaths) op.SetSubsetAttrs(sksascurrent, sketchframedef); // this goes again and gets the subsets into the areas from those on the paths for (OneSArea osa : vsareas) osa.SetSubsetAttrsA(true, sksascurrent); return res; } ///////////////////////////////////////////// public void paintWqualitySketch(GraphicsAbstraction ga, int irenderingquality, Map subsetattrstylesmap) { assert OnePathNode.CheckAllPathCounts(vnodes, vpaths); // if subsetattrstylesmap == null then we assume we're drawing a framed sketch, // so subset selection gets ignored and we don't recurse into subsubrames // set up the hasrendered flags to begin with for (OneSArea osa : vsareas) osa.bHasrendered = false; for (ConnectiveComponentAreas cca : sksya.vconncom) cca.bHasrendered = false; for (OnePathNode opn : vnodes) opn.pathcountch = 0; // count these up as we draw them // go through the paths and render those at the bottom here and aren't going to be got later pwqPathsNonAreaNoLabels(ga); // go through the areas and complete the paths as we tick them off. for (OneSArea osa : vsareas) { // fill the area with a diffuse colour (only if it's a drawing kind) if ((subsetattrstylesmap == null) || !bRestrictSubsetCode || osa.bareavisiblesubset) // setting just for previewing { // draw the wall type strokes related to this area (the fat white boundaries around the strokes) if (bWallwhiteoutlines) pwqWallOutlinesArea(ga, osa); if (osa.iareapressig == SketchLineStyle.ASE_KEEPAREA) ga.pwqFillArea(osa); // could have these sorted by group subset style, and remake it for these if ((osa.iareapressig == SketchLineStyle.ASE_SKETCHFRAME) && (osa.opsketchframedefs != null) && (!bRestrictSubsetCode || osa.bareavisiblesubset)) { // multiple cases are rare, so convenient to sort them on the fly for dynamicness. if (osa.opsketchframedefs.size() >= 2) { Collections.sort(osa.opsketchframedefs, new Comparator() { public int compare(OnePath op1, OnePath op2) { if (op1.plabedl.sketchframedef.sfnodeconnzsetrelative != op2.plabedl.sketchframedef.sfnodeconnzsetrelative) return (op1.plabedl.sketchframedef.sfnodeconnzsetrelative - op2.plabedl.sketchframedef.sfnodeconnzsetrelative < 0.0F ? -1 : 1); return op1.plabedl.sketchframedef.distinctid - op2.plabedl.sketchframedef.distinctid; }}); } for (OnePath op : osa.opsketchframedefs) { // the plotting of an included image SketchFrameDef sketchframedef = op.plabedl.sketchframedef; if (sketchframedef.pframeimage != null) { if ((irenderingquality == 1) || (irenderingquality == 3)) { ga.startFrame((!sketchframedef.sfstyle.equals("notrim") ? osa : null), sketchframedef.pframesketchtrans); Image img = sketchframedef.pframeimage.GetImage(true); ga.drawImage(img); ga.endFrame(); } else ga.fillArea(osa, colframebackgroundimageshow); // signifies that something's there (deliberately overpaints sketches when there's more than one, so it's visible) continue; } // the plotting of the sketch if (sketchframedef.pframesketch == null) continue; if (subsetattrstylesmap == null) // avoids recursion continue; //assert sketchframedef.pframesketch.sksascurrent != null; SubsetAttrStyle sksas = null; if (!sketchframedef.sfstyle.equals("")) { sksas = subsetattrstylesmap.get(sketchframedef.sfstyle); if (sksas == null) TN.emitWarning("sfstyle='"+sketchframedef.sfstyle+"' not found"); } if (sksas == null) { TN.emitMessage("failed to get sfstyle "+sketchframedef.sfstyle+" so getting default"); sksas = subsetattrstylesmap.get("default"); if (sksas == null) TN.emitError("groupsubsetattr groupsubsetname='default' not found in fontcolours"); } // this supresses an assertion error that happens when trying to // do the witches in place hack of an sketch on the centreline //assert (sksas != null); // it has to at least be set to something; if it has been loaded in the background if (sksas == null) { for (String s : subsetattrstylesmap.keySet()) TN.emitMessage("Bad subsetattrstylesmap missing default, key="+s); } if ((sksas != null) && ((sksas != sketchframedef.pframesketch.sksascurrent) || !sketchframedef.pframesketch.submappingcurrent.equals(sketchframedef.submapping) || ((irenderingquality == 3) && !sketchframedef.pframesketch.bSymbolLayoutUpdated))) { int iProper = (irenderingquality == 3 ? SketchGraphics.SC_UPDATE_ALL : SketchGraphics.SC_UPDATE_ALL_BUT_SYMBOLS); TN.emitMessage("-- Resetting sketchstyle to " + sksas.stylename + " during rendering"); int scchangetyp = sketchframedef.pframesketch.SetSubsetAttrStyle(sksas, sketchframedef); SketchGraphics.SketchChangedStatic(scchangetyp, sketchframedef.pframesketch, null); assert (sksas == sketchframedef.pframesketch.sksascurrent); assert sketchframedef.pframesketch.submappingcurrent.equals(sketchframedef.submapping); // if iproper == SketchGraphics.SC_UPDATE_ALL (not SketchGraphics.SC_UPDATE_ALL_BUT_SYMBOLS) // then it could do it as through a window so that not the whole thing needs redoing. sketchframedef.pframesketch.UpdateSomething(iProper, false); SketchGraphics.SketchChangedStatic(iProper, sketchframedef.pframesketch, null); } assert this != sketchframedef.pframesketch; sketchframedef.pframesketch.bRestrictSubsetCode = false; ga.startFrame(osa, sketchframedef.pframesketchtrans); TN.emitMessage("Drawing the frame round: " + sketchframedef.sfsketch + " " + sketchframedef.sfelevrotdeg); if ((sketchframedef.sfelevrotdeg == 0.0) && !sketchframedef.sfelevvertplane.equals("extunfold")) sketchframedef.pframesketch.paintWqualitySketch(ga, irenderingquality, null); else sketchframedef.paintWelevSketch(ga, sksas, true); ga.endFrame(); } } } assert !osa.bHasrendered; osa.bHasrendered = true; pwqSymbolsOnArea(ga, osa); pwqPathsOnAreaNoLabels(ga, osa, null); } // check for success for (OnePath op : vpaths) { //assert (op.ciHasrendered >= 2; if (op.ciHasrendered < 2) TN.emitWarning("ciHasrenderedbad on path:" + vpaths.indexOf(op)); } // labels // check any paths if they are now done for (OnePath op : vpaths) { if ((op.linestyle != SketchLineStyle.SLS_CENTRELINE) && (op.plabedl != null) && (op.plabedl.labfontattr != null)) { if ((subsetattrstylesmap == null) || !bRestrictSubsetCode || op.bpathvisiblesubset) op.paintLabel(ga, null); } } } ///////////////////////////////////////////// public void paintWbkgd(GraphicsAbstraction ga, boolean bHideCentreline, boolean bHideMarkers, int stationnamecond, boolean bHideSymbols, Collection tsvpathsviz, Collection tsvpathsvizbound, Collection tsvareasviz, Collection tsvnodesviz, boolean bzthinnedvisible) { // draw all the paths inactive. for (OnePath op : tsvpathsviz) { if (!bHideCentreline || (op.linestyle != SketchLineStyle.SLS_CENTRELINE)) { boolean bIsSubsetted = (!bRestrictSubsetCode || op.bpathvisiblesubset); // we draw subsetted kinds as quality for now if (!bzthinnedvisible) op.paintW(ga, bIsSubsetted, false); else if (op.gpzsliced != null) op.paintWzthinned(ga, bIsSubsetted); } } // tsvpathsvizbound are the paths on the boundary between the areas that are selected by z and those which aren't, so do them in grey if ((tsvpathsvizbound != null) && !bzthinnedvisible) for (OnePath op : tsvpathsvizbound) { if (!bHideCentreline || (op.linestyle != SketchLineStyle.SLS_CENTRELINE)) op.paintW(ga, false, false); } // draw all the nodes inactive if (!bHideMarkers) { for (OnePathNode opn : tsvnodesviz) { if (!bRestrictSubsetCode || (opn.icnodevisiblesubset != 0)) ga.drawShape(opn.Getpnell(), SketchLineStyle.pnlinestyleattr); } } // draw all the station names inactive if (stationnamecond != 0) { //ga.setStroke(SketchLineStyle.linestylestrokes[SketchLineStyle.SLS_DETAIL]); //ga.setColor(SketchLineStyle.fontcol); //ga.setFont(SketchLineStyle.defaultfontlab); for (OnePathNode opn : tsvnodesviz) { if (opn.IsCentrelineNode()) { if (!bRestrictSubsetCode || (opn.icnodevisiblesubset != 0)) { String slab; if (stationnamecond == 2) slab = String.valueOf((int)(opn.zalt * 0.1)); else slab = opn.ShortStationLabel(); ga.drawString(slab, SketchLineStyle.stationPropertyFontAttr, (float)opn.pn.getX() + SketchLineStyle.strokew * 2, (float)opn.pn.getY() - SketchLineStyle.strokew); } } } } // render all the symbols without clipping. if (!bHideSymbols) { for (OnePath op : tsvpathsviz) { if (!bRestrictSubsetCode || op.bpathvisiblesubset) { for (OneSSymbol oss : op.vpsymbols) oss.paintW(ga, false, false); } } } // shade in the areas according to depth for (OneSArea osa : tsvareasviz) { assert osa.subsetattr != null; if ((!bRestrictSubsetCode || osa.bareavisiblesubset) && (osa.subsetattr.areacolour != null)) { if (SketchLineStyle.bDepthColours) ga.fillArea(osa, SketchLineStyle.GetColourFromCollam(osa.icollam, true)); else ga.fillArea(osa, osa.subsetattr.areacolour); } } } } tunnelx-20140102.orig/src/ConnectiveLabelTabPane.java0000644000000000000000000001173311762432750017225 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2004 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import javax.swing.JComboBox; import javax.swing.JPanel; import javax.swing.JButton; import java.awt.BorderLayout; import java.awt.GridLayout; import javax.swing.JCheckBox; import java.awt.Font; import javax.swing.JToggleButton; import javax.swing.JTextField; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JLabel; import javax.swing.JRadioButton; import javax.swing.ButtonGroup; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.SortedMap; import java.util.TreeMap; import java.util.Map; import java.util.List; import java.util.ArrayList; ///////////////////////////////////////////// class ConnectiveLabelTabPane extends JPanel { JComboBox fontstyles = new JComboBox(); List lfontstyles = new ArrayList(); JButton jbcancel = new JButton("Cancel Label"); JTextArea labtextfield = new JTextArea("how goes\n there"); JScrollPane scrollpanetextfield = new JScrollPane(labtextfield); JCheckBox jcbarrowpresent = new JCheckBox("Arrow"); JCheckBox jcbboxpresent = new JCheckBox("Box"); // the positioning of the text JTextField tfxrel = new JTextField(); JTextField tfyrel = new JTextField(); // these codes could be expended later; they are numbered 0-4 clockwise from bottom left static String[] rppos = { "-1", "0", "1" }; ///////////////////////////////////////////// class radbut implements ActionListener { String xrel; String yrel; radbut(int ipos) { xrel = rppos[(ipos % 3)]; yrel = rppos[2 - (ipos / 3)]; } public void actionPerformed(ActionEvent e) { tfxrel.setText(xrel); tfyrel.setText(yrel); tfxrel.postActionEvent(); } } ButtonGroup buttgroup = new ButtonGroup(); JRadioButton[] rbposes = new JRadioButton[10]; radbut[] radbuts = new radbut[9]; SortedMap fontssortedmap = new TreeMap(); ///////////////////////////////////////////// void ReloadLabelsCombo(SubsetAttrStyle sascurrent) { fontssortedmap.clear(); for (SubsetAttr sa : sascurrent.msubsets.values()) { for (LabelFontAttr lfa : sa.labelfontsmap.values()) { if (!fontssortedmap.containsKey(lfa.labelfontname)) fontssortedmap.put(lfa.labelfontname, String.format("%s (%s)", lfa.labelfontname, sa.subsetname)); } } fontstyles.removeAllItems(); lfontstyles.clear(); for (Map.Entry foename : fontssortedmap.entrySet()) { fontstyles.addItem(foename.getKey()); // the value has the subset in brackets, but subsets will in future be common to most styles //fontstyles.addItem(foename.getValue()); lfontstyles.add(foename.getKey()); } } ///////////////////////////////////////////// void setTextPosCoords(float fxrel, float fyrel) { int ix = (fxrel == -1.0F ? 0 : (fxrel == 0.0F ? 1 : (fxrel == 1.0F ? 2 : -1))); int iy = (fyrel == -1.0F ? 2 : (fyrel == 0.0F ? 1 : (fyrel == 1.0F ? 0 : -1))); if ((ix != -1) && (iy != -1)) { rbposes[ix + iy * 3].setSelected(true); tfxrel.setText(rppos[ix]); tfyrel.setText(rppos[2 - iy]); } else { rbposes[9].setSelected(true); tfxrel.setText(String.valueOf(fxrel)); tfyrel.setText(String.valueOf(fyrel)); } } ///////////////////////////////////////////// ConnectiveLabelTabPane() { super(new BorderLayout()); JPanel fsp = new JPanel(new GridLayout(1, 3)); JPanel fsp1 = new JPanel(new GridLayout(2, 1)); fsp1.add(jcbarrowpresent); fsp1.add(jcbboxpresent); fsp.add(fsp1); JPanel fsp3 = new JPanel(new GridLayout(3, 3)); for (int i = 0; i < 10; i++) { rbposes[i] = new JRadioButton(""); buttgroup.add(rbposes[i]); if (i != 9) { radbuts[i] = new radbut(i); rbposes[i].addActionListener(radbuts[i]); fsp3.add(rbposes[i]); } } fsp.add(fsp3); JPanel fsp2 = new JPanel(new GridLayout(2, 1)); fsp2.add(tfxrel); fsp2.add(tfyrel); fsp.add(fsp2); JPanel fsps = new JPanel(); fsps.add(fontstyles); fsps.add(jbcancel); add(fsp, BorderLayout.NORTH); add(scrollpanetextfield, BorderLayout.CENTER); add(fsps, BorderLayout.SOUTH); } }; tunnelx-20140102.orig/src/GraphicsAbstraction.java0000644000000000000000000003717612261213471016670 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2006 Martin Green. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.util.Iterator; import java.awt.Graphics2D; import java.awt.Color; import java.awt.BasicStroke; import java.awt.Shape; import java.awt.Rectangle; import java.awt.geom.Area; import java.awt.Font; import java.awt.geom.AffineTransform; import java.awt.geom.FlatteningPathIterator; import java.awt.geom.PathIterator; import java.awt.geom.GeneralPath; import java.awt.geom.Rectangle2D; import java.awt.geom.Line2D; import java.awt.Image; // // // GraphicsAbstraction // // ///////////////////////////////////////////// // This will eventually be the base class for all graphics interacton public class GraphicsAbstraction { Graphics2D g2d; Rectangle depthcolourswindowrect = null; // used for thinning the height maps double depthcolourswidthstep = -1.0; private Shape mainclip = null; private AffineTransform preframetrans = null; private Shape frameclip = null; // active if not null GraphicsAbstraction(Graphics2D pg2d) // can also be SvgGraphics2D { g2d = pg2d; mainclip = g2d.getClip(); } private void setColor(Color c) { g2d.setColor(c); } private void setStroke(BasicStroke bs) { g2d.setStroke(bs); } private void draw(Shape shape) { assert shape != null; try { g2d.draw(shape); } catch (java.lang.ArithmeticException e) { TN.emitMessage("caught ArithmeticException in java2d library g2d.draw(shape)"); } catch (java.lang.InternalError e) { TN.emitMessage("caught InternalError in java2d library g2d.draw(shape)"); } catch (java.lang.NullPointerException e) { TN.emitMessage("caught NullPointerException in java2d library g2d.draw(shape)"); } } private void fill(Shape shape) { g2d.fill(shape); } private void setFont(Font font) { g2d.setFont(font); } private void drawString(String s, Float x, Float y) { g2d.drawString(s, x, y); } private Shape getClip() { return g2d.getClip(); } private void setClip(Shape shape) { //System.out.println("setclip " + shape.getBounds2D(getTransform())); g2d.setClip(shape); } private void clip(Shape shape) { g2d.clip(shape); } private AffineTransform getTransform() { return g2d.getTransform(); } private void setTransform(AffineTransform at) { g2d.setTransform(at); //mainclip = g2d.getClip(); } void transform(AffineTransform at) { g2d.transform(at); //mainclip = g2d.getClip(); } void SetMainClip() { mainclip = g2d.getClip(); } Boolean hit(Rectangle rect, Shape shape, Boolean bool) { return g2d.hit(rect, shape, bool); } //Algorithms to handle clipping void startSymbolClip(OneSArea osa) { clip(osa.aarea); //Intersects the current clip with gparea } void startSymbolClip(ConnectiveComponentAreas cca) { clip(cca.saarea); //Intersects the current clip with gparea } void startAccPolyClip(Shape shap) { clip(shap); } void endClip() { setClip(frameclip != null ? frameclip : mainclip); } void startFrame(OneSArea osa, AffineTransform at) { System.out.println("startframe " + g2d.getClipBounds()); assert frameclip == null; if (osa != null) clip(osa.gparea); assert preframetrans == null; preframetrans = getTransform(); transform(at); frameclip = getClip(); // this must be got after the transform // assert frameclip != null; } // mainclip = g2d.getClip(); void endFrame() { // assert frameclip != null; setTransform(preframetrans); preframetrans = null; frameclip = null; setClip(mainclip); System.out.println("endframe " + g2d.getClipBounds() + " " + mainclip); } void drawString(String s, LabelFontAttr lfa, float x, float y) { drawString(s, lfa, x, y, null); } void drawString(String s, LabelFontAttr lfa, float x, float y, Color color) { setFont(lfa.fontlab); setColor(color != null ? color : lfa.labelcolour); drawString(s, x, y); } void drawlabel(PathLabelDecode pld, float x, float y, Color labelcolour) { // draw the box outline of the whole label if (labelcolour == null) labelcolour = pld.labfontattr.labelcolour; if ((pld.bboxpresent) && (pld.rectdef != null)) { setColor(labelcolour); assert pld.labfontattr.labelstroke != null; setStroke(pld.labfontattr.labelstroke); draw(pld.rectdef); } //draw the text for (PathLabelElement ple : pld.vdrawlablns) { // the black and white rectangles if (ple.text.equals("%blackrect%")) { setColor(labelcolour); g2d.fill(ple.textshape); } // what makes this complicated is that a straight outline exceeds the boundary of the rectangle, so must be trimmed. The line is then halfwidth else if (ple.text.equals("%whiterect%")) { setColor(labelcolour); assert pld.labfontattr.labelstroke != null; setStroke(pld.labfontattr.labelstroke); startAccPolyClip(ple.textshape); draw(ple.textshape); endClip(); } // we could fill translucent for the writing to show up better // or put this into the rectef above, unioning the different // rectangles that are slightly expanded else { //setColor(Color.red); //g2d.fill(ple.textrect); if (ple.bfontmagnifyset) { Font dfont = pld.labfontattr.fontlab.deriveFont(ple.fontmagnify * pld.labfontattr.fontlab.getSize()); System.out.println("font sizes " + pld.labfontattr.fontlab.getSize() + " " + dfont.getSize() + " on text " + ple.text); setFont(dfont); } else setFont(pld.labfontattr.fontlab); setColor(labelcolour); drawString(ple.text, (float)(ple.textrect.getX() + ple.ftextjustify * (pld.drawlabxwid - ple.textwidth)), (float)ple.textrect.getY() + (float)ple.textrect.getHeight() - pld.fmdescent); } } //Draw arrow if (pld.barrowpresent) { for (int i = 0; i < pld.arrowdef.length; i++) { setStroke(pld.labfontattr.labelstroke); setColor(labelcolour); if (pld.arrowdef[i] != null) draw(pld.arrowdef[i]); } } } void drawPath(OnePath op, LineStyleAttr linestyleattr) { drawPath(op, linestyleattr, null); } void drawPath(OnePath op, LineStyleAttr linestyleattr, Color color) { //assert linestyleattr.strokecolour != null; assert op != null; // set the colour setColor(color != null ? color : linestyleattr.strokecolour); if (op.linestyle == SketchLineStyle.SLS_FILLED) { fill(op.gp); return; } // set the stroke assert linestyleattr.linestroke != null; setStroke(linestyleattr.linestroke); // special spiked type things if (linestyleattr.spikeheight != 0.0F) { assert ((op.linestyle == SketchLineStyle.SLS_PITCHBOUND) || (op.linestyle == SketchLineStyle.SLS_CEILINGBOUND)); drawDottedPath(op, linestyleattr.strokewidth / 2, linestyleattr.gapleng, linestyleattr.spikegap, linestyleattr.spikeheight); } // other visible strokes else draw(op.gp); } void drawPathzthinned(OnePath op, LineStyleAttr linestyleattr, Color color) { assert op != null; assert op.gpzsliced != null; // set the colour setColor(color != null ? color : linestyleattr.strokecolour); if (op.linestyle == SketchLineStyle.SLS_FILLED) { fill(op.gpzsliced); return; } // set the stroke assert linestyleattr.linestroke != null; setStroke(linestyleattr.linestroke); draw(op.gpzsliced); } void drawShape(Shape shape, LineStyleAttr linestyleattr) { drawShape(shape, linestyleattr, null); } void drawShape(Shape shape, LineStyleAttr linestyleattr, Color color) // Just used for odd things like dotted cut out rectangles { // set the colour setColor(color != null ? color : linestyleattr.strokecolour); // set the stroke if (linestyleattr != null) { assert linestyleattr.linestroke != null; setStroke(linestyleattr.linestroke); } //Draw the shape draw(shape); } ///////////////////////////////////////////// boolean drawDottedPath(OnePath op, float flatness, float gapleng, float spikegap, float spikeheight) { float[] coords = new float[6]; float[] pco = new float[op.nlines * 6 + 2]; // maybe we will do this without flattening paths in the future. FlatteningPathIterator fpi = new FlatteningPathIterator(op.gp.getPathIterator(null), flatness); if (fpi.currentSegment(coords) != PathIterator.SEG_MOVETO) TN.emitProgError("move to not first"); // put in the moveto. float lx = coords[0]; float ly = coords[1]; // (gapleng == 0.0F) means pitch bound. int scanmode = (gapleng == 0.0F ? 1 : 0); // 0 for blank, 1 for approaching a spike, 2 for leaving a spike. float dotleng = spikegap - gapleng; if (dotleng <= 0.0) return TN.emitWarning("Dotleng "+dotleng+ " spikegap="+spikegap+" gapleng="+gapleng); float scanlen = dotleng / 2; fpi.next(); while (!fpi.isDone()) { int curvtype = fpi.currentSegment(coords); //if (curvtype == PathIterator.SEG_LINETO) if (curvtype != PathIterator.SEG_LINETO) TN.emitProgError("Flattened not lineto"); // measure the distance to the coords. float vx = coords[0] - lx; float vy = coords[1] - ly; float dfco = (float)Math.sqrt(vx * vx + vy * vy); float lam = 0.0F; float dfcoR = dfco; float lxR = lx; float lyR = ly; boolean bCont = false; while ((scanlen <= dfcoR) && (lam != 1.0F) && (dfcoR != 0.0F)) { // find the lam where this ends float lam1 = Math.min(1.0F, lam + scanlen / dfco); float lx1 = lx + vx * lam1; float ly1 = ly + vy * lam1; if (scanmode != 0) { draw(new Line2D.Float(lxR, lyR, lx1, ly1)); } lxR = lx1; lyR = ly1; lam = lam1; dfcoR -= scanlen; // spike if necessary if (scanmode == 1) { // right hand spike. if (spikeheight != 0.0F) draw(new Line2D.Float(lxR, lyR, lxR - vy * spikeheight / dfco, lyR + vx * spikeheight / dfco)); if (gapleng != 0.0F) { scanmode = 2; scanlen = spikegap / 2; } else scanlen = spikegap; } else if (scanmode == 0) { scanlen = spikegap / 2; scanmode = 1; } else { scanlen = dotleng; scanmode = 0; } } if (scanmode != 0) draw(new Line2D.Float(lxR, lyR, coords[0], coords[1])); scanlen -= dfcoR; lx = coords[0]; ly = coords[1]; fpi.next(); } return true; } ///////////////////////////////////////////// double revangle(int i) { if (i == 0) return 0.0; int irs = 1; int ir = 0; while (i != 0) { ir = ir << 1; if ((i & 1) != 0) ir++; irs = irs << 1; i = i >> 1; } return (double)ir / irs; } ///////////////////////////////////////////// void drawHatchedArea(OneSArea osa, int isa) { if (osa.gparea == null) return; System.out.println("revangle " + isa + ": " + revangle(isa)); // make the hatch path. GeneralPath gphatch; { gphatch = new GeneralPath(); // find the region we will make our parallel lines in. Rectangle2D r2d = osa.rboundsarea; double midx = r2d.getX() + r2d.getWidth() / 2; double midy = r2d.getY() + r2d.getHeight() / 2; double mrad = Math.sqrt(r2d.getWidth() * r2d.getWidth() + r2d.getHeight() * r2d.getHeight()) / 2; double mtheta = Math.PI * revangle(isa) + 0.12345F; double vx = Math.cos(mtheta); double vy = Math.sin(mtheta); double sp = SketchLineStyle.strokew * 5.0F; int gg = (int)(mrad / sp + 1.0F); for (int i = -gg; i <= gg; i++) { double scx = midx + vy * sp * i; double scy = midy - vx * sp * i; gphatch.moveTo((float)(scx - vx * mrad), (float)(scy - vy * mrad)); gphatch.lineTo((float)(scx + vx * mrad), (float)(scy + vy * mrad)); } } // we have the hatching path. now draw it clipped. Sybmol Clip is used as hatching works simialarly to symbols startSymbolClip(osa); drawShape(gphatch, (isa % 2) == 0 ? SketchLineStyle.linestylehatch1 : SketchLineStyle.linestylehatch2); endClip(); } void fillArea(ConnectiveComponentAreas cca, Color color) { setColor(color); fill(cca.saarea); } void fillArea(OneSArea osa, Color color) { setColor(color); fill(osa.aarea); if (osa.Dgptriangulation != null) { setColor(Color.black); int Di = 0; for (DelEdge de : osa.Dgptriangulation.dledgelist) { Di++; if (de.sig == 1) setColor(Color.green); else if (de.sig == -1) setColor(Color.red); else setColor(Color.black); if (de.sig != -2) { draw(new Line2D.Double(de.a.pn.getX(), de.a.pn.getY(), de.b.pn.getX(), de.b.pn.getY()+Di*0.001)); } } } } void drawSymbol(OneSSymbol oss, LineStyleAttr linestyleattr) { if (oss.gpsymps == null) return; setColor(linestyleattr.strokecolour); if (oss.ssb.bFilledType) fill(oss.gpsymps); else { setStroke(linestyleattr.linestroke); draw(oss.gpsymps); } } ///////////////////////////////////////////// void drawImage(Image img) { try { g2d.drawImage(img, null, null); } catch (NoClassDefFoundError e) { TN.emitWarning("Out of memory error while drawing image"); } } ///////////////////////////////////////////// // make gradient shading within an area void pwqFillArea(OneSArea osa) { assert osa.subsetattr != null; if (osa.subsetattr.areamaskcolour != null) //This shadow lightens the background, I think this should be combined with drawing the colour fillArea(osa, osa.subsetattr.areamaskcolour); if (osa.subsetattr.areacolour == null) return; if (!SketchLineStyle.bDepthColours) { fillArea(osa, osa.subsetattr.areacolour); return; } /////////////// // this is the depth colours shading part assert (depthcolourswindowrect != null); if (!g2d.hit(depthcolourswindowrect, osa.aarea, false)) { // (ordinary fill case, though shouldn't be there anyway) fillArea(osa, osa.subsetattr.areacolour); return; } startSymbolClip(osa); assert depthcolourswidthstep > 0.0; int ix0 = (int)Math.floor(osa.rboundsarea.getX() / depthcolourswidthstep); int ix1 = (int)Math.ceil((osa.rboundsarea.getX() + osa.rboundsarea.getWidth()) / depthcolourswidthstep); int iy0 = (int)Math.floor(osa.rboundsarea.getY() / depthcolourswidthstep); int iy1 = (int)Math.ceil((osa.rboundsarea.getY() + osa.rboundsarea.getHeight()) / depthcolourswidthstep); for (int ix = ix0; ix < ix1; ix++) { for (int iy = iy0; iy < iy1; iy++) { float licollam = osa.GetAvgLocIcollam((ix + 0.5) * depthcolourswidthstep, (iy + 0.5) * depthcolourswidthstep); setColor(SketchLineStyle.GetColourFromCollam(licollam, true)); fill(new Rectangle2D.Double(ix * depthcolourswidthstep, iy * depthcolourswidthstep, depthcolourswidthstep, depthcolourswidthstep)); } } endClip(); } } tunnelx-20140102.orig/src/OneLeg.java0000644000000000000000000001461412261213471014077 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.Graphics; import java.io.IOException; // // // OneLeg // // class OneLeg { // the station names and their pointers String stfrom; boolean bsurfaceleg = false; String stto; String svxtitle; // used for loading in with subsets on the centreline String svxdate; // used to animate changes in order String svxteam; // used to create attibution text in atlas OneStation osfrom = null; OneStation osto = null; // the measured vector (in polar and cartesian) boolean bnosurvey = false; float tape; float compass; float backcompass; boolean bUseClino; // depth stuff float clino; float backclino; float fromdepth; float todepth; boolean bcartesian = false; // sets the vector directly boolean btopextendedelevationflip = false; // used for the extended elevation direction // the calculated vector Vec3 mlegvec = new Vec3(); final static float INVALID_COMPASSCLINO = -999.0F; ///////////////////////////////////////////// void SetParasLLF(LegLineFormat llf) { bsurfaceleg = llf.bsurface; svxtitle = llf.bb_svxtitle; svxdate = llf.bb_svxdate; svxteam = llf.sb_totalteam.toString(); } ///////////////////////////////////////////// OneLeg(OneLeg ol) { stfrom = ol.stfrom; bsurfaceleg = ol.bsurfaceleg; stto = ol.stto; svxtitle = ol.svxtitle; svxdate = ol.svxdate; svxteam = ol.svxteam; osfrom = ol.osfrom; osto = ol.osto; bnosurvey = ol.bnosurvey; tape = ol.tape; compass = ol.compass; backcompass = ol.backcompass; bUseClino = ol.bUseClino; clino = ol.clino; backclino = ol.backclino; fromdepth = ol.fromdepth; todepth = ol.todepth; bcartesian = ol.bcartesian; btopextendedelevationflip = ol.btopextendedelevationflip; mlegvec = ol.mlegvec; } ///////////////////////////////////////////// OneLeg(String lstfrom, String lstto, float ltape, float lcompass, float lbackcompass, float lclino, float lbackclino, LegLineFormat llf) { stfrom = lstfrom; stto = lstto; tape = ltape; compass = lcompass; backcompass = lbackcompass; bUseClino = true; clino = lclino; backclino = lbackclino; bcartesian = false; SetParasLLF(llf); // update from measurments if ((lcompass == INVALID_COMPASSCLINO) && (lbackcompass != INVALID_COMPASSCLINO)) lcompass = lbackcompass + 180.0F; if ((lclino == INVALID_COMPASSCLINO) && (lbackclino != INVALID_COMPASSCLINO)) lclino = -lbackclino; float cc = tape * (float)TN.degcos(lclino); float cz = tape * (float)TN.degsin(lclino); if (!llf.btopextendedelevation) mlegvec.SetXYZ(cc * (float)TN.degsin(lcompass), cc * (float)TN.degcos(lcompass), cz); else { btopextendedelevationflip = llf.btopextflipleg; mlegvec.SetXYZ(cc, cz, 0.0F); // flipping depends on which direction we come at the edge } } ///////////////////////////////////////////// OneLeg(String lstfrom, String lstto, LegLineFormat llf) { stfrom = lstfrom; stto = lstto; SetParasLLF(llf); bnosurvey = true; } ///////////////////////////////////////////// OneLeg(String lstfrom, String lstto, float ltape, float lcompass, float lfromdepth, float ltodepth, LegLineFormat llf) { stfrom = lstfrom; stto = lstto; tape = ltape; compass = lcompass; backcompass = INVALID_COMPASSCLINO; bUseClino = false; fromdepth = lfromdepth; todepth = ltodepth; bcartesian = false; SetParasLLF(llf); // update from measurments mlegvec.z = todepth - fromdepth; float ccsq = tape * tape - mlegvec.z * mlegvec.z; float cc = (float)Math.sqrt(ccsq >= 0.0F ? ccsq : 0.0F); mlegvec.x = cc * (float)TN.degsin(compass); mlegvec.y = cc * (float)TN.degcos(compass); } ///////////////////////////////////////////// // cartesian setting, differentiated by rearranging the parameters OneLeg(float ldx, float ldy, float ldz, String lstfrom, String lstto, LegLineFormat llf) { stfrom = lstfrom; stto = lstto; tape = -1.0F; compass = -1.0F; bUseClino = false; bcartesian = true; SetParasLLF(llf); mlegvec.SetXYZ(ldx, ldy, ldz); } ///////////////////////////////////////////// OneLeg(String lstto, float fx, float fy, float fz, LegLineFormat llf) { stfrom = null; stto = lstto; // maybe calculate measure tape = -1.0F; compass = -1.0F; clino = -1.0F; SetParasLLF(llf); // update from measurments mlegvec.SetXYZ(fx, fy, fz); } ///////////////////////////////////////////// void paintW(Graphics g, boolean bHighLightActive, DepthCol depthcol) { // get rid of fixed point vectors if (stfrom == null) return; // get rid of date restrictions if ((depthcol != null) && (svxdate.compareTo(depthcol.datelimit) > 0)) return; boolean bHighlight = false; if ((depthcol == null) || bHighlight) { g.setColor(bHighlight ? TN.wfmpointActive : TN.wfmLeg); g.drawLine(osfrom.TLocX, osfrom.TLocY, osto.TLocX, osto.TLocY); } // funny colors else { // for now do from lowest range. // TN.xsgLines : float zfrom = osfrom.Loc.z; float zto = osto.Loc.z; int izfrom = (int)((zfrom - depthcol.zlo) / (depthcol.zhi - depthcol.zlo) * depthcol.znslices); if (izfrom < 0) izfrom = 0; if (izfrom >= depthcol.znslices) izfrom = depthcol.znslices - 1; g.setColor(depthcol.col[izfrom]); g.drawLine(osfrom.TLocX, osfrom.TLocY, osto.TLocX, osto.TLocY); } } public String toString() { return "OneLeg " + (stfrom == null ? "null" : stfrom) + " " + stto + (bnosurvey ? " nosurvey" : ""); } } tunnelx-20140102.orig/src/OneSArea.java0000644000000000000000000004656512261213471014375 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.geom.Line2D; import java.awt.geom.Area; import java.awt.geom.Point2D; import java.awt.geom.Ellipse2D; import java.awt.geom.Rectangle2D; import java.awt.Shape; import java.awt.geom.AffineTransform; import java.awt.geom.GeneralPath; import java.awt.geom.PathIterator; import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.AffineTransform; import java.io.IOException; import java.awt.BasicStroke; import java.awt.image.BufferedImage; import java.awt.Color; import java.awt.TexturePaint; import java.awt.Rectangle; import java.util.List; import java.util.ArrayList; // // // OneSArea // // ///////////////////////////////////////////// class OneSArea implements Comparable { // defines the area. GeneralPath gparea = null; // if null then nothing should be done with it. DelTriangulation Dgptriangulation = null; // experimental Area aarea = null; Rectangle2D rboundsarea = null; float zalt = 0.0F; float icollam = 0.0F; boolean bareavisiblesubset = false; List vssubsetattrs = new ArrayList(); // SubsetAttr (in parallel) from the current style SubsetAttr subsetattr = null; // one chosen from the vector above // array of RefPathO. List refpaths = new ArrayList(); List refpathsub = new ArrayList(); // subselection without the trees. List connpathrootscen = new ArrayList(); // used to free up pointer to an area, and for centrelines when they are drawn on top of areas int nconnpathremaining; // the index into connpathrootscen where AttachRemainingCentrelines was called, so we know what not to add as associations in the select areas // ConnectiveComponentAreas this area is in List ccalist = new ArrayList(); // these are used to mark the areas for inclusion in sketchsymbolareas. more efficient than setting false it as a booleans. // int iamark = 0; // static int iamarkl = 1; int distinctoaid; // used for the comparator as this is in a hashset static int Sdistinctoaid = 1; // used in the quality rendering for signaling which edges can be drawn once areas on both sides have been done. boolean bHasrendered = false; // maximized around the contour for right precedence // ASE_ type int iareapressig = SketchLineStyle.ASE_KEEPAREA; // 0-1 normal, 3 column(rock), 2 pitchhole List opsketchframedefs = null; // when iareapressig is SketchLineStyle.ASE_SKETCHFRAME, and we have a framed sketch. This object specifies the transformations // used for refering to the area in SVG files String svgid = null; GeneralPath gpzslicedarea = null; ///////////////////////////////////////////// void paintHatchW(GraphicsAbstraction ga, int isa) { if (gparea != null) ga.drawHatchedArea(this, isa); } ///////////////////////////////////////////// // we're going to use this to help sort vareas. the zalt values better not change throughout the age of this object public int compareTo(OneSArea osa) { if (zalt != osa.zalt) return (zalt - osa.zalt < 0.0F ? -1 : 1); return distinctoaid - osa.distinctoaid; // was: return hashCode() - osa.hashCode(), which caused errors when two distinct areas had the same hashcode and the second didn't make it into vsareas } ///////////////////////////////////////////// // find which subsets this area is in, by looking at the surrounding edges // this is different to the isubsetcode thing; something between these two is redundant // not used. void DecideSubsets(List lvssubsets) { assert lvssubsets.isEmpty(); for (RefPathO rpo : refpathsub) { // find the intersection between these sets (using string equalities) List pvssub = rpo.op.vssubsets; if (!lvssubsets.isEmpty()) { for (int j = lvssubsets.size() - 1; j >= 0; j--) { if (!pvssub.contains(lvssubsets.get(j))) lvssubsets.remove(j); } if (lvssubsets.isEmpty()) break; } else lvssubsets.addAll(pvssub); } } ///////////////////////////////////////////// int SetSubsetAttrsA(boolean bremakesubset, SubsetAttrStyle sas) { if (bremakesubset) { vssubsetattrs.clear(); int i = 0; for (RefPathO rpo : refpathsub) { // find the intersection between these sets (using string equalities) List pvssub = rpo.op.vssubsetattrs; if (i != 0) { for (int j = vssubsetattrs.size() - 1; j >= 0; j--) { if (!pvssub.contains(vssubsetattrs.get(j))) vssubsetattrs.remove(j); } } else vssubsetattrs.addAll(pvssub); i++; } // no overlapping values, find default if (!vssubsetattrs.isEmpty()) subsetattr = vssubsetattrs.get(vssubsetattrs.size() - 1); // gets last one (could choose the highest priority one -- eg one that forces to hide) else subsetattr = sas.sadefault; assert subsetattr != null; } // set the visibility flag bareavisiblesubset = true; for (RefPathO rpo : refpaths) { if (!rpo.op.bpathvisiblesubset) bareavisiblesubset = false; } return (bareavisiblesubset ? 1 : 0); } ///////////////////////////////////////////// // this function should be a generic one on general paths ///////////////////////////////////////////// // it looks tempting to do this on the refpaths, but since that list is // equivalent to the general path, it might as well be keopt simple and not piecewise static float[] CText = new float[4]; static float[] CTdir = new float[4]; ///////////////////////////////////////////// static void CommitTriplet(float xp, float yp, float x, float y, float xn, float yn, boolean bFirst) { boolean bleft = (bFirst || (x <= CText[0])); boolean bup = (bFirst || (y >= CText[1])); boolean bright = (bFirst || (x >= CText[2])); boolean bdown = (bFirst || (y <= CText[3])); if (bleft || bup || bright || bdown) { float vpx = xp - x; float vpy = yp - y; float vnx = xn - x; float vny = yn - y; float vextd = vpx * vny - vpy * vnx; float vdot = vpx * vnx + vpy * vpy; if (bleft) { CText[0] = x; CTdir[0] = vextd; } if (bup) { CText[1] = y; CTdir[1] = vextd; } if (bright) { CText[2] = x; CTdir[2] = vextd; } if (bdown) { CText[3] = y; CTdir[3] = vextd; } } } ///////////////////////////////////////////// static float[] Fcoords = new float[6]; static float FxL1, FyL1; static float FxP2, FyP2; static float FxP1, FyP1; static float FxP0, FyP0; ///////////////////////////////////////////// static int FindOrientationReliable(GeneralPath gp) { PathIterator pi = gp.getPathIterator(null); int np = -1; while (true) { int curvtype = pi.currentSegment(Fcoords); if (curvtype == PathIterator.SEG_CLOSE) break; np++; assert (np != 0) || (curvtype == PathIterator.SEG_MOVETO); FxP2 = FxP1; FyP2 = FyP1; FxP1 = FxP0; FyP1 = FyP0; if (curvtype == PathIterator.SEG_CUBICTO) { FxP0 = Fcoords[4]; FyP0 = Fcoords[5]; } else { FxP0 = Fcoords[0]; FyP0 = Fcoords[1]; } if (np == 1) { FxL1 = FxP0; FyL1 = FyP0; } if (np >= 2) CommitTriplet(FxP2, FyP2, FxP1, FyP1, FxP0, FyP0, (np == 2)); pi.next(); } //assert (Fcoords[0] == FcoordsL0[0]) && (Fcoords[1] == FcoordsL0[1]); CommitTriplet(FxP1, FyP1, FxP0, FyP0, FxL1, FyL1, false); if (np <= 2) return 0; boolean bpos = ((CTdir[0] >= 0.0) && (CTdir[1] >= 0.0) && (CTdir[2] >= 0.0) && (CTdir[3] >= 0.0)); boolean bneg = ((CTdir[0] <= 0.0) && (CTdir[1] <= 0.0) && (CTdir[2] <= 0.0) && (CTdir[3] <= 0.0)); if (bpos != bneg) return (bpos ? 1 : -1); return 0; } ///////////////////////////////////////////// void Setkapointers() { // we should perform the hard task of reflecting certain paths in situ. for (RefPathO refpath : refpaths) { // get the ref path. if (refpath.bFore) { assert refpath.op.karight == null; refpath.op.karight = this; } else { assert refpath.op.kaleft == null; refpath.op.kaleft = this; } } } ///////////////////////////////////////////// void SetkapointersClear() { // we should perform the hard task of reflecting certain paths in situ. for (RefPathO refpath : refpaths) { // get the ref path. if (refpath.bFore) { assert refpath.op.karight == this; refpath.op.karight = null; } else { assert refpath.op.kaleft == this; refpath.op.kaleft = null; } } for (OnePath op : connpathrootscen) { // this assertion can fail if we've changed a line type from centreline to wall. In these cases we should delete and add in instead as it changes the structure of the drawing assert (op.linestyle == SketchLineStyle.SLS_CONNECTIVE) || ((op.linestyle == SketchLineStyle.SLS_CENTRELINE) && (op.kaleft == this) && (op.karight == this)); if (op.kaleft == this) op.kaleft = null; if (op.karight == this) op.karight = null; } for (ConnectiveComponentAreas cca : ccalist) { assert cca.vconnareas.contains(this); cca.vconnareas.remove(this); for (OnePath cop : cca.vconnpaths) { assert (cop.kaleft != this); assert (cop.karight != this); } } } ///////////////////////////////////////////// /* void LinkZslicedArea() { // go round and append paths on these just like that. // then plot with the trimmed areas and so on. // simplify the trimmed area plotting // also decide whether the OnePathNode is within the selection gpzslicedarea = null; new GeneralPath(GeneralPath.WIND_EVEN_ODD); // use the gpzsliced paths done by the MakeTilted area void MakeTilted(double zlo, double zhi, double scaTiltZ, AffineTransform currtrans) // we should perform the hard task of reflecting certain paths in situ. boolean bfirst = true; for (RefPathO refpath : refpathsub) { // if going forwards, then everything works if (refpath.bFore) { gparea.append(refpath.op.gp, !bfirst); // the second parameter is continuation, and avoids repeats at the moveto bfirst = false; continue; } // specially decode it if reversed if ((pco == null) || (pco.length < refpath.op.nlines * 6 + 2)); pco = new float[refpath.op.nlines * 6 + 2]; // this gives an array that is interspersed with the control points refpath.op.ToCoordsCubic(pco); // now put in the reverse coords. if (bfirst) { gparea.moveTo(pco[refpath.op.nlines * 6], pco[refpath.op.nlines * 6 + 1]); bfirst = false; } for (int i = refpath.op.nlines - 1; i >= 0; i--) { int i6 = i * 6; if ((pco[i6 + 2] == pco[i6]) && (pco[i6 + 3] == pco[i6 + 1])) // and the next point too. gparea.lineTo(pco[i6], pco[i6 + 1]); else gparea.curveTo(pco[i6 + 4], pco[i6 + 5], pco[i6 + 2], pco[i6 + 3], pco[i6], pco[i6 + 1]); } } gparea.closePath(); } */ ///////////////////////////////////////////// static float[] pco = null; // this makes a mess out of reversing a general path void LinkArea() { assert gparea == null; gparea = new GeneralPath(GeneralPath.WIND_EVEN_ODD); // we should perform the hard task of reflecting certain paths in situ. boolean bfirst = true; for (RefPathO refpath : refpathsub) { // if going forwards, then everything works if (refpath.bFore) { gparea.append(refpath.op.gp, !bfirst); // the second parameter is continuation, and avoids repeats at the moveto bfirst = false; continue; } // specially decode it if reversed if ((pco == null) || (pco.length < refpath.op.nlines * 6 + 2)); pco = new float[refpath.op.nlines * 6 + 2]; // this gives an array that is interspersed with the control points refpath.op.ToCoordsCubic(pco); // now put in the reverse coords. if (bfirst) { gparea.moveTo(pco[refpath.op.nlines * 6], pco[refpath.op.nlines * 6 + 1]); bfirst = false; } for (int i = refpath.op.nlines - 1; i >= 0; i--) { int i6 = i * 6; if ((pco[i6 + 2] == pco[i6]) && (pco[i6 + 3] == pco[i6 + 1])) // and the next point too. gparea.lineTo(pco[i6], pco[i6 + 1]); else gparea.curveTo(pco[i6 + 4], pco[i6 + 5], pco[i6 + 2], pco[i6 + 3], pco[i6], pco[i6 + 1]); } } gparea.closePath(); } ///////////////////////////////////////////// void SetCentrelineThisArea(OnePath op, boolean bremaining) { assert op.linestyle == SketchLineStyle.SLS_CENTRELINE; assert op.karight == op.kaleft; if (op.karight != null) { if (compareTo(op.karight) <= 0) { assert zalt <= op.karight.zalt; return; } assert zalt >= op.karight.zalt; boolean bD = op.karight.connpathrootscen.remove(op); assert bD; } op.karight = this; op.kaleft = this; connpathrootscen.add(op); assert !bremaining || (connpathrootscen.size() > nconnpathremaining); } ///////////////////////////////////////////// void MarkCentrelineRoot(OnePath op, boolean bFore) { OnePathNode opn = (bFore ? op.pnstart : op.pnend); assert opn.IsCentrelineNode(); // track round the centreline node OnePath opC = op; boolean bForeC = bFore; do { if (!bForeC) { bForeC = !opC.bapfrfore; opC = opC.apforeright; } else { bForeC = !opC.baptlfore; opC = opC.aptailleft; } assert opn == (bForeC ? opC.pnstart : opC.pnend); if (opC.linestyle == SketchLineStyle.SLS_CENTRELINE) SetCentrelineThisArea(opC, false); } while (!((opC == op) && (bForeC == bFore))); // end of do loop } ///////////////////////////////////////////// // construction from wherever OneSArea(OnePath lop, boolean lbFore) // edge scans to the right { // loop round to the start. OnePath op = lop; boolean bFore = lbFore; assert lop.AreaBoundingType(); iareapressig = SketchLineStyle.ASE_KEEPAREA; // reset in the loop if anything found opsketchframedefs = null; zalt = 0.0F; // default distinctoaid = Sdistinctoaid++; do { // gone wrong. if (op == null) break; refpaths.add(new RefPathO(op, bFore)); // jumps to the next segment on the next node OnePathNode opnN = (bFore ? op.pnend : op.pnstart); if (bFore) { bFore = !op.bapfrfore; op = op.apforeright; } else { bFore = !op.baptlfore; op = op.aptailleft; } assert opnN == (bFore ? op.pnstart : op.pnend); // go round that segment until we find an area bounding type while (!op.AreaBoundingType()) { // look for any area killing symbols if ((op.linestyle == SketchLineStyle.SLS_CONNECTIVE) && (op.plabedl != null)) { if ((op.plabedl.barea_pres_signal != SketchLineStyle.ASE_HCOINCIDE) && (op.plabedl.barea_pres_signal != SketchLineStyle.ASE_ZSETRELATIVE) && (op.plabedl.barea_pres_signal != SketchLineStyle.ASE_ELEVATIONPATH)) iareapressig = Math.max(iareapressig, op.plabedl.barea_pres_signal); if (op.IsSketchFrameConnective()) { if (opsketchframedefs == null) opsketchframedefs = new ArrayList(); opsketchframedefs.add(op); } } // mark the connective types anyway, as a root-start. if (op.linestyle == SketchLineStyle.SLS_CONNECTIVE) { if (!bFore) op.karight = this; else op.kaleft = this; connpathrootscen.add(op); } if (op.linestyle == SketchLineStyle.SLS_CENTRELINE) SetCentrelineThisArea(op, false); if (!bFore) { bFore = !op.bapfrfore; op = op.apforeright; } else { bFore = !op.baptlfore; op = op.aptailleft; } assert opnN == (bFore ? op.pnstart : op.pnend); } // endwhile (!op.AreaBoundingType()) } while (!((op == lop) && (bFore == lbFore))); // end of do loop // set the pointers from paths to this area Setkapointers(); if (op == null) { assert false; return; } // now make the refpathsub by copying over and removing duplicates (as we track down the back side of a tree). for (int i = 0; i < refpaths.size(); i++) { OnePath opsi = refpaths.get(i).op; OnePath opsl = (refpathsub.isEmpty() ? null : refpathsub.get(refpathsub.size() - 1).op); if (opsi != opsl) refpathsub.add(refpaths.get(i)); else refpathsub.remove(refpathsub.size() - 1); } // tree duplicates between the beginning and the end while ((refpathsub.size() >= 2) && (refpathsub.get(0).op == refpathsub.get(refpathsub.size() - 1).op)) { refpathsub.remove(refpathsub.size() - 1); refpathsub.remove(0); } // this builds the general path which defines the area // set up the area if something is empty. if (refpathsub.isEmpty()) { iareapressig = SketchLineStyle.ASE_KILLAREA; // don't render (outer tree?) return; // it turned out to be just a tree } // now we construct the general path from the list of untreed areas LinkArea(); try { aarea = new Area(gparea); } catch (java.lang.InternalError e) // this is to see a very rare failure in the area generating algorithm { TN.emitWarning("Library Error creating Area from boundary"); System.out.println(e.toString()); //System.out.println("Number of nodes " + gparea.); System.out.println("bounding box " + gparea.getBounds2D()); aarea = null; } //if (refpathsub.size() != refpaths.size()) // TN.emitMessage("pathedges " + refpathsub.size() + " over total path edges " + refpaths.size()); rboundsarea = gparea.getBounds(); // set the zaltitude by finding the average height // (altitude must have been set from the linking already) float szalt = 0.0F; for (RefPathO rpo : refpathsub) szalt += rpo.ToNode().zalt; if (refpathsub.size() != 0) zalt = szalt / refpathsub.size(); for (int i = connpathrootscen.size() - 1; i >= 0; i--) { OnePath llop = connpathrootscen.get(i); if (llop.pnstart.IsCentrelineNode()) MarkCentrelineRoot(llop, true); else if (llop.pnend.IsCentrelineNode()) MarkCentrelineRoot(llop, false); } nconnpathremaining = connpathrootscen.size(); } ////////////////////////////////////////// float GetAvgLocIcollam(double x, double y) { double tot = 0.0; double wtot = 0.0; for (RefPathO rpo : refpathsub) { OnePathNode opn = rpo.ToNode(); double xd = opn.pn.getX() - x; double yd = opn.pn.getY() - y; double radsq = xd * xd + yd * yd; if (radsq == 0.0) return opn.icollam; double w = 1 / radsq; tot += w; wtot += opn.icollam * w; } return (float)(tot != 0.0 ? wtot / tot : 1.0); } ////////////////////////////////////////// void setId(String id) { this.svgid = id; } ////////////////////////////////////////// String getId() { return this.svgid; } } tunnelx-20140102.orig/src/MatchSketchCentrelines.java0000644000000000000000000004164712261213471017326 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2008 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.util.Arrays; import java.util.List; import java.util.ArrayList; import java.util.Stack; import java.util.Collections; import java.util.Collection; import java.util.Map; import java.util.HashMap; import java.util.Set; import java.util.HashSet; // // // MatchSketchCentrelines // // ///////////////////////////////////////////// class PrefixLeg { OnePath op; String pnlabtail; String pnlabhead; float vx; float vy; // the begin-blocks for the tail and head labels String pnlabblocktail; String pnlabblockhead; String pnlabstationtail; String pnlabstationhead; // matching destination PrefixLeg pltmember = null; ///////////////////////////////////////////// String desc() { return "Prefixleg "+pnlabtail+" "+pnlabhead+" "+vx+","+vy; } ///////////////////////////////////////////// PrefixLeg(OnePath lop) { op = lop; pnlabtail = op.plabedl.centrelinetail.replaceAll("[|^]", "."); pnlabhead = op.plabedl.centrelinehead.replaceAll("[|^]", "."); int dotpnlabtail = pnlabtail.lastIndexOf("."); pnlabblocktail = (dotpnlabtail != -1 ? pnlabtail.substring(0, dotpnlabtail) : ""); pnlabstationtail = (dotpnlabtail != -1 ? pnlabtail.substring(dotpnlabtail + 1) : pnlabtail); int dotpnlabhead = pnlabhead.lastIndexOf("."); pnlabblockhead = (dotpnlabhead != -1 ? pnlabhead.substring(0, dotpnlabhead) : ""); pnlabstationhead = (dotpnlabhead != -1 ? pnlabhead.substring(dotpnlabhead + 1) : pnlabhead); vx = (float)(op.pnend.pn.getX() - op.pnstart.pn.getX()); vy = (float)(op.pnend.pn.getY() - op.pnstart.pn.getY()); } ///////////////////////////////////////////// String FindCommonPrefix(PrefixLeg pl) { if (pnlabtail.endsWith(pl.pnlabtail) && pnlabhead.endsWith(pl.pnlabhead)) { int lpt = pl.pnlabtail.length(); int lph = pl.pnlabhead.length(); int lt = pnlabtail.length(); int lh = pnlabhead.length(); if ((lpt == lt) && (lph == lh)) return ""; int ldt = lt - lpt - 1; int ldh = lh - lph - 1; if ((ldt >= 0) && (pnlabtail.charAt(ldt) == '.') && (ldh >= 0) && (pnlabhead.charAt(ldh) == '.')) { String prefixt = pnlabtail.substring(0, ldt + 1); // include the dot String prefixh = pnlabhead.substring(0, ldh + 1); if (prefixt.equals(prefixh)) return prefixt; } } return null; } ///////////////////////////////////////////// float CompareDirection(PrefixLeg pl) { float lsq = vx * vx + vy * vy; float losq = pl.vx * pl.vx + pl.vy * pl.vy; float dot = vx * pl.vx + vy * pl.vy; if (dot == 0.0F) return 0.0F; return Math.max(0.0F, dot / Math.max(lsq, losq)); } } ///////////////////////////////////////////// class PrefixCount implements Comparable { String prefixfrom; String prefix; float score = 0.0F; int nscore = 0; int nlegsfrom = 0; int nlegsto = 0; int i; // used when we are sorting by best for each prefix PrefixCount(String lprefixfrom, String lprefix, int li, int lnlegsfrom, int lnlegsto) { prefixfrom = lprefixfrom; prefix = lprefix; i = li; nlegsfrom = lnlegsfrom; nlegsto = lnlegsto; } float avgscore() { float pres = score / Math.max(1, nscore); if (prefixfrom.equals(prefix)) pres = (3 + pres) / 4; // -2 attempt to mask mismatch on low numbers (eg 7 legs) where the end points are equated to something else and count against float fac = 1.0F * nscore / Math.max(Math.max(nlegsfrom-2, nlegsto), 1); return fac * pres; } String desc() { return "avgscore="+avgscore() + " prefix="+prefix + " prefixfrom="+prefixfrom + " score="+score+ " nscore="+nscore+ " nlegsfrom="+ nlegsfrom + " nlegsto=" + nlegsto; } public int compareTo(PrefixCount opc) { return (int)Math.signum(opc.avgscore() - avgscore()); } } ///////////////////////////////////////////// ///////////////////////////////////////////// class MatchSketchCentrelines { List blocknamesfrom = new ArrayList(); List blocknamesto = new ArrayList(); List prefixlegsfrom = new ArrayList(); List prefixlegsto = new ArrayList(); List prefixlegsfromunmatched = new ArrayList(); Map nodemapping = new HashMap(); ///////////////////////////////////////////// Map GetBlockMapping() { // make the lists of blocknames Map > mblocknamesto = new HashMap >(); for (PrefixLeg plt : prefixlegsto) { if (!mblocknamesto.containsKey(plt.pnlabblocktail)) mblocknamesto.put(plt.pnlabblocktail, new ArrayList()); if (!mblocknamesto.containsKey(plt.pnlabblockhead)) mblocknamesto.put(plt.pnlabblockhead, new ArrayList()); if (plt.pnlabblocktail.equals(plt.pnlabblockhead)) mblocknamesto.get(plt.pnlabblocktail).add(plt); } blocknamesto.addAll(mblocknamesto.keySet()); Map > mblocknamesfrom = new HashMap >(); for (PrefixLeg plf : prefixlegsfrom) { if (!mblocknamesfrom.containsKey(plf.pnlabblocktail)) mblocknamesfrom.put(plf.pnlabblocktail, new ArrayList()); if (!mblocknamesfrom.containsKey(plf.pnlabblockhead)) mblocknamesfrom.put(plf.pnlabblockhead, new ArrayList()); if (plf.pnlabblocktail.equals(plf.pnlabblockhead)) mblocknamesfrom.get(plf.pnlabblocktail).add(plf); } blocknamesfrom.addAll(mblocknamesfrom.keySet()); // make the arrays of prefixcounts from-to List< List > blockcorresp = new ArrayList< List >(); for (int i = 0; i < blocknamesfrom.size(); i++) { List pclist = new ArrayList(); for (int j = 0; j < blocknamesto.size(); j++) { String blocknamefrom = blocknamesfrom.get(i); String blocknameto = blocknamesto.get(j); /*System.out.println("\n\nblocknamefrom="+blocknamefrom); for (PrefixLeg p : mblocknamesfrom.get(blocknamefrom)) System.out.println(p.desc()); System.out.println("blocknameto="+blocknameto); for (PrefixLeg p : mblocknamesto.get(blocknameto)) System.out.println(p.desc()); */ pclist.add(new PrefixCount(blocknamefrom, blocknameto, i, mblocknamesfrom.get(blocknamefrom).size(), mblocknamesto.get(blocknameto).size())); } blockcorresp.add(pclist); } // insert all the possible corresponding edges according to each blockname and station names for (PrefixLeg plf : prefixlegsfrom) { if (!plf.pnlabblocktail.equals(plf.pnlabblockhead)) continue; for (PrefixLeg plt : prefixlegsto) { if (!plt.pnlabblocktail.equals(plt.pnlabblockhead)) continue; if (plf.pnlabstationtail.equals(plt.pnlabstationtail) && plf.pnlabstationhead.equals(plt.pnlabstationhead)) { int i = blocknamesfrom.indexOf(plf.pnlabblocktail); int j = blocknamesto.indexOf(plt.pnlabblocktail); PrefixCount pc = blockcorresp.get(i).get(j); pc.score += plt.CompareDirection(plf); pc.nscore++; } } } // print out the likely correspondences List bestcorresp = new ArrayList(); for (int i = 0; i < blocknamesfrom.size(); i++) { Collections.sort(blockcorresp.get(i)); PrefixCount pc = blockcorresp.get(i).get(0); bestcorresp.add(pc); // pc.i helps find it again } Collections.sort(bestcorresp); // the map of blocknames to blocknames; connect first match to first match Map blockmapping = new HashMap(); for (PrefixCount pc : bestcorresp) { for (PrefixCount tpc : blockcorresp.get(pc.i)) { if (blockmapping.values().contains(tpc.prefix) || (tpc.nscore == 0)) continue; TN.emitMessage("MM: " + tpc.desc()); if (true || (tpc.avgscore() > 0.5)) blockmapping.put(blocknamesfrom.get(pc.i), tpc.prefix); else TN.emitWarning("Rejecting map: "+tpc.desc()+" not enough agreement/overlap.\n\nPerhaps take out excess unmatched centrelines from source sketch"); break; } } return blockmapping; /* // not very smart n^2 algorithm Map prefixcounts = new HashMap(); for (PrefixLeg plf : prefixlegsfrom) { for (PrefixLeg plt : prefixlegsto) // the n^2 loop thing { String prefix = plt.FindCommonPrefix(plf); if (prefix != null) { PrefixCount prefixcount = prefixcounts.get(prefix); if (prefixcount == null) { prefixcount = new PrefixCount(prefix, -1); prefixcounts.put(prefix, prefixcount); } prefixcount.score += plt.CompareDirection(plf); } } } List prefixcountlist = new ArrayList(); prefixcountlist.addAll(prefixcounts.values()); Collections.sort(prefixcountlist); for (PrefixCount prefixcount : prefixcountlist) System.out.println("Probable prefix: '" + prefixcount.prefix + "' score: " + prefixcount.score); return (!prefixcountlist.isEmpty() ? prefixcountlist.get(0).prefix : null); */ } ///////////////////////////////////////////// PrefixLeg IncreCorresp(PrefixLeg plf) { OnePathNode mpnstart = nodemapping.get(plf.op.pnstart); OnePathNode mpnend = nodemapping.get(plf.op.pnend); if ((mpnstart == null) && (mpnend == null)) return null; // find the destination line that best shares the direction PrefixLeg pltbest = null; float pltbestcompare = 0.0F; for (PrefixLeg plt : prefixlegsto) { if (((mpnstart == null) || (mpnstart == plt.op.pnstart)) && ((mpnend == null) || (mpnend == plt.op.pnend))) { float pltcompare = plf.CompareDirection(plt); if ((pltbest == null) || (pltcompare > pltbestcompare)) { pltbest = plt; pltbestcompare = pltcompare; } } } return pltbest; } ///////////////////////////////////////////// boolean NodeMappingPut(OnePathNode opnf, OnePathNode opnt) { OnePathNode lopnt = nodemapping.get(opnf); if (lopnt == null) nodemapping.put(opnf, opnt); else if (lopnt != opnt) // returns false return !TN.emitWarning("NodeMappingPut mismatch:" + opnt.pnstationlabel + " " + lopnt.pnstationlabel); return true; } ///////////////////////////////////////////// // need to find a mapping from centrelines in one to the other. boolean CorrespMatching(List vpathsfrom, List vpathsto) { // add the paths into the prefixlegs structures for (OnePath opt : vpathsto) { if ((opt.linestyle == SketchLineStyle.SLS_CENTRELINE) && (opt.plabedl != null) && opt.plabedl.IsCentrelineType()) prefixlegsto.add(new PrefixLeg(opt)); } for (OnePath opf : vpathsfrom) { if ((opf.linestyle == SketchLineStyle.SLS_CENTRELINE) && (opf.plabedl != null) && opf.plabedl.IsCentrelineType()) prefixlegsfrom.add(new PrefixLeg(opf)); } // make the likely mapping of blocks Map blockmapping = GetBlockMapping(); if (blockmapping.size() == 0) return false; // make the lookup table for centreline names Map tolegnamemap = new HashMap(); for (PrefixLeg plt : prefixlegsto) tolegnamemap.put(plt.pnlabblocktail + "." + plt.pnlabstationtail + " " + plt.pnlabblockhead + "." + plt.pnlabstationhead, plt); for (PrefixLeg plf : prefixlegsfrom) { String tpnlabblocktail = blockmapping.get(plf.pnlabblocktail); String tpnlabblockhead = blockmapping.get(plf.pnlabblockhead); if ((tpnlabblocktail != null) && (tpnlabblockhead != null)) { String toleglookup = tpnlabblocktail + "." + plf.pnlabstationtail + " " + tpnlabblockhead + "." + plf.pnlabstationhead; PrefixLeg plt = tolegnamemap.remove(toleglookup); if (plt != null) { plf.pltmember = plt; if (!NodeMappingPut(plf.op.pnstart, plt.op.pnstart)) return false; if (!NodeMappingPut(plf.op.pnend, plt.op.pnend)) return false; } else prefixlegsfromunmatched.add(plf); } else prefixlegsfromunmatched.add(plf); } TN.emitMessage("SMS+ " + prefixlegsfromunmatched.size() + " " + prefixlegsfrom.size()); while (true) { int prefixlegsfromunmatchedsize = prefixlegsfromunmatched.size(); for (int i = prefixlegsfromunmatchedsize - 1; i >= 0; i--) { PrefixLeg plf = prefixlegsfromunmatched.get(i); PrefixLeg plt = IncreCorresp(plf); if (plt != null) { plf.pltmember = plt; if (!NodeMappingPut(plf.op.pnstart, plt.op.pnstart)) return false; if (!NodeMappingPut(plf.op.pnend, plt.op.pnend)) return false; } prefixlegsfromunmatched.remove(i); } if (prefixlegsfromunmatched.isEmpty() || (prefixlegsfromunmatched.size() == prefixlegsfromunmatchedsize)) break; } System.out.println("SSS+ " + prefixlegsfromunmatched.size() + " " + prefixlegsfrom.size()); return true; } ///////////////////////////////////////////// static OnePath FindBestStationpairMatch(List vpaths, String pnstartlabel, String pnendlabel, String subset) { while (true) { OnePath opcorresp = null; for (OnePath op : vpaths) { if ((op.pnstart != null) && (subset == null ? (op.linestyle == SketchLineStyle.SLS_CENTRELINE) : (((op.linestyle == SketchLineStyle.SLS_CENTRELINE) || (op.linestyle == SketchLineStyle.SLS_CENTRELINE)) && op.vssubsets.contains(subset)))) { if (op.pnstart.pnstationlabel.endsWith(pnstartlabel) && op.pnend.pnstationlabel.endsWith(pnendlabel) && ((op.pnstart.pnstationlabel.length() == pnstartlabel.length()) || (op.pnstart.pnstationlabel.charAt(op.pnstart.pnstationlabel.length() - pnstartlabel.length() - 1) == '.')) && ((op.pnend.pnstationlabel.length() == pnendlabel.length()) || (op.pnend.pnstationlabel.charAt(op.pnend.pnstationlabel.length() - pnendlabel.length() - 1) == '.'))) opcorresp = op; } } if (opcorresp != null) return opcorresp; // trim off a shared name between the labels TN.emitMessage("No corresponding leg found for elevation segment " + pnstartlabel + " " + pnendlabel); int dotstart = pnstartlabel.indexOf('.'); int dotend = pnendlabel.indexOf('.'); if ((dotstart == -1) || (dotend == -1) || (dotstart != dotend) || !pnstartlabel.startsWith(pnendlabel.substring(0, dotend))) return null; pnstartlabel = pnstartlabel.substring(dotstart + 1); pnendlabel = pnendlabel.substring(dotend + 1); TN.emitMessage("Trimming to " + pnstartlabel + " " + pnendlabel); } } } tunnelx-20140102.orig/src/DepthCol.java0000644000000000000000000000415511762432750014437 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.Color; import java.util.List; import java.util.ArrayList; // separates the different colours for depth drawing. class DepthCol { boolean bByAbssolute; // Range in depth. float zlo; float zhi; // number of slices int znslices; Color[] col; // date list List svxdates = new ArrayList(); String datelimit = ""; ///////////////////////////////////////////// void SetDateLimit(double slv) { int idl = Math.min(svxdates.size() - 1, (int)(slv * svxdates.size())); datelimit = (idl != -1 ? svxdates.get(idl) : ""); System.out.println("datelimit " + datelimit); } ///////////////////////////////////////////// DepthCol() { znslices = 10; col = new Color[znslices]; for (int i = 0; i < znslices; i++) { float scz = (float)i / znslices; col[i] = new Color(Color.HSBtoRGB(scz, 1.0F, 1.0F)); } } ///////////////////////////////////////////// // find the range of stations void AbsorbRange(OneStation os, boolean bFirst) { float zval = os.Loc.z; if (bFirst) { zlo = zval; zhi = zlo; } else if (zlo > zval) zlo = zval; else if (zhi < zval) zhi = zval; } } tunnelx-20140102.orig/src/PrintScaleDialog.java0000644000000000000000000001301011762432750016107 0ustar package Tunnel; // defunct import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.text.*; import javax.swing.event.*; public class PrintScaleDialog implements DocumentListener { double trueHeight; // decimeters... double trueWidth; final double imageableWidth; final double imageableHeight; JDialog layouterDialog; JPanel layouterPanel; JTextField scale; JLabel sizeLabel, sizeLabel2, pageSizeLabel, pageSizeLabel2, scaleLabel, pagesLabel, pagesLabel2; JCheckBox cutoutrectangle = new JCheckBox("Cutout rectangle", true); JCheckBox forceonepage = new JCheckBox("Centred one page", false); JCheckBox singlepageenabled = new JCheckBox("Single page", false); JLabel singlepagelabel = new JLabel("page nx : page ny"); JTextField pagenx = new JTextField(); JTextField pageny = new JTextField(); JButton doCalculate; JButton fitPage; JButton allDone; // Constructor public PrintScaleDialog(JFrame frame, double w, double h, double pointsw, double pointsh) { trueHeight = h; trueWidth = w; imageableWidth = pointsw/72*0.254; imageableHeight = pointsh/72*0.254; // Create the Dialog and container. layouterDialog = new JDialog(frame, "Print scale and layout", true); layouterDialog.setSize(60, 80); layouterPanel = new JPanel(); layouterPanel.setLayout(new GridLayout(0, 2)); // Add the widgets. addWidgets(); // Add the panel to the Dialog. layouterDialog.getContentPane().add(layouterPanel, BorderLayout.CENTER); // Exit when the window is closed. layouterDialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); // Show the layouter. layouterDialog.pack(); layouterDialog.setVisible(true); } // Create and add the widgets for layouter. private void addWidgets() { // Create widgets. sizeLabel = new JLabel("True size: ", SwingConstants.RIGHT); sizeLabel2 = new JLabel(Double.toString(Math.rint(trueWidth/10)) + " x " + Double.toString(Math.rint(trueHeight/10)) + "m", SwingConstants.LEFT); pageSizeLabel = new JLabel("Page image area: ", SwingConstants.RIGHT); pageSizeLabel2 = new JLabel(Double.toString(Math.rint(imageableWidth*1000)/100) + " x " + Double.toString(Math.rint(imageableHeight*1000)/100) + "cm", SwingConstants.LEFT); scale = new JTextField(4); scaleLabel = new JLabel("Scale 1 :", SwingConstants.RIGHT); //doCalculate = new JButton("Calculate..."); pagesLabel = new JLabel("Pages:", SwingConstants.RIGHT); pagesLabel2 = new JLabel("", SwingConstants.LEFT); fitPage = new JButton("Fit to page"); allDone = new JButton("OK"); scale.getDocument().addDocumentListener(this); fitPage.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent event) { int fscale = (int) Math.floor(Math.max(trueWidth/imageableWidth, trueHeight/imageableHeight)*1.01); scale.setText(Integer.toString(fscale)); } }); allDone.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent event) { try { int tscale = Integer.parseInt(scale.getText()); layouterDialog.setVisible(false); } catch(Exception e) {} // Don't close window if scale isn't a valid number } }); layouterDialog.addWindowListener( new WindowListener() { public void windowClosing(WindowEvent e) { scale.setText("-1"); layouterDialog.setVisible(false); } // the following are irrelevant to a modal dialog public void windowOpened(WindowEvent e) {} public void windowIconified(WindowEvent e) {} public void windowDeiconified(WindowEvent e) {} public void windowDeactivated(WindowEvent e) {} public void windowClosed(WindowEvent e) {} public void windowActivated(WindowEvent e) {} }); // Add widgets to container. layouterPanel.add(sizeLabel); layouterPanel.add(sizeLabel2); layouterPanel.add(pageSizeLabel); layouterPanel.add(pageSizeLabel2); layouterPanel.add(scaleLabel); layouterPanel.add(scale); //layouterPanel.add(doCalculate); layouterPanel.add(pagesLabel); layouterPanel.add(pagesLabel2); layouterPanel.add(forceonepage); layouterPanel.add(cutoutrectangle); layouterPanel.add(singlepagelabel); layouterPanel.add(singlepageenabled); layouterPanel.add(pagenx); layouterPanel.add(pageny); layouterPanel.add(fitPage); layouterPanel.add(allDone); scaleLabel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); pagesLabel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); scale.setText(Integer.toString(TN.prtscale)); } public void handleDocumentEvent(DocumentEvent event) { try { int tscale = Integer.parseInt(scale.getText()); int pagesAcross = 1 + (int) Math.floor(trueWidth / tscale / imageableWidth); int pagesUp = 1 + (int) Math.floor(trueHeight / tscale / imageableHeight); pagesLabel2.setText(Integer.toString(pagesAcross*pagesUp) + " pages (" + Integer.toString(pagesAcross) + "x" + Integer.toString(pagesUp) + ")"); } catch(Exception e) {} } public void insertUpdate(DocumentEvent event) { handleDocumentEvent(event); } public void removeUpdate(DocumentEvent event) { handleDocumentEvent(event); } public void changedUpdate(DocumentEvent event) { handleDocumentEvent(event); } public int getScale() { return Integer.parseInt(scale.getText()); } // // main method // public static void main(String[] args) // { // try // { // UIManager.setLookAndFeel( // UIManager.getCrossPlatformLookAndFeelClassName()); // } // catch(Exception e) {} // // PrintLayouter layouter = new PrintLayouter(330,650); // } } tunnelx-20140102.orig/src/TunnelXML.java0000644000000000000000000002202011762432750014552 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.io.IOException; import java.io.BufferedReader; import java.io.InputStream; import java.io.Reader; import java.io.StringReader; import java.io.FileReader; import java.io.StreamTokenizer; import java.io.InputStreamReader; ///////////////////////////////////////////// // local class of the parser. class TunnelXML { TunnelXMLparsebase txp; StreamTokenizer st; String erm = null; FileAbstraction ssfile = null; ///////////////////////////////////////////// TunnelXML() { } ///////////////////////////////////////////// boolean ParseFile(TunnelXMLparsebase ltxp, FileAbstraction sfile) { ssfile = sfile; boolean bRes = false; InputStream inputstream = null; try { inputstream = sfile.GetInputStream(); Reader br = new BufferedReader(new InputStreamReader(inputstream)); String erm = ParseReader(ltxp, br, true); if (erm != null) TN.emitError(erm + " on line " + st.lineno() + " of " + sfile.getName()); else bRes = true; br.close(); inputstream.close(); } catch (IOException e) { TN.emitWarning(e.toString()); } catch (Exception e) { e.printStackTrace(); TN.emitError(e.toString() + "\n on line " + st.lineno() + " of " + sfile.getName()); } // important to close, or the django runserver will hang if (inputstream != null) { try { inputstream.close(); } catch (IOException e) { TN.emitWarning(e.toString()); } } return bRes; } ///////////////////////////////////////////// String ParseString(TunnelXMLparsebase ltxp, String stxt) { String erm = null; try { erm = ParseReader(ltxp, new StringReader(stxt), false); } catch (IOException e) { TN.emitError(e.toString()); e.printStackTrace(); return "IOError"; } catch (Exception e) { e.printStackTrace(); TN.emitError(e.toString() + "\n on line " + st.lineno()); return "Other error"; } if (erm != null) TN.emitWarning(erm + " in: " + stxt); return erm; } ///////////////////////////////////////////// String ParseReader(TunnelXMLparsebase ltxp, Reader br, boolean bOfFile) throws IOException { txp = ltxp; st = new StreamTokenizer(br); st.resetSyntax(); st.whitespaceChars('\u0000', '\u0020'); st.wordChars('A', 'Z'); st.wordChars('a', 'z'); st.wordChars('0', '9'); st.wordChars('\u00A0', '\u00FF'); // we don't implement XML entities since label text gets mangled on its own, and everything else is data not text. String swdchs = ".-_+^:;|*()[]{}&%$!,#~@"; for (int i = 0; i < swdchs.length(); i++) st.wordChars(swdchs.charAt(i), swdchs.charAt(i)); st.quoteChar('"'); if (bOfFile) st.quoteChar('\''); // this is converted to a word-char right after the header else st.wordChars('\'', '\''); erm = ParseTokens(st); br.close(); return erm; } static int AS_OUTSIDE = 0; static int AS_FIRST_OPEN = 1; static int AS_END_ELEMENT_SLASH = 2; static int AS_END_ELEMENT_EMITTED = 3; static int AS_START_ELEMENT = 4; static int AS_ATT_SEQ_OUTSIDE = 5; static int AS_QM_HEADER = 6; static int AS_ATT_SEQ_EQ = 7; static int AS_ATT_SEQ_SET = 8; static int AS_COMMENT = 9; int mAngleBracketState = AS_OUTSIDE; String name; String attname; ///////////////////////////////////////////// String ParseTokens(StreamTokenizer st) throws IOException { mAngleBracketState = AS_OUTSIDE; String prevcommtoken = ""; while (st.nextToken() != StreamTokenizer.TT_EOF) { //TN.emitMessage("lineno: " + st.lineno() + " state: " + mAngleBracketState); switch (st.ttype) { case '?': if (mAngleBracketState == AS_FIRST_OPEN) mAngleBracketState = AS_QM_HEADER; else if (mAngleBracketState == AS_QM_HEADER) { mAngleBracketState = AS_END_ELEMENT_EMITTED; st.wordChars('\'', '\''); } else if (mAngleBracketState == AS_OUTSIDE) txp.characters("?"); else if (mAngleBracketState == AS_COMMENT) ; else return "Angle ? Brackets mismatch"; break; case '<': if (mAngleBracketState == AS_COMMENT) break; else if (mAngleBracketState != AS_OUTSIDE) return "Angle Brackets mismatch"; mAngleBracketState = AS_FIRST_OPEN; break; case '/': if (mAngleBracketState == AS_FIRST_OPEN) mAngleBracketState = AS_END_ELEMENT_SLASH; else if (mAngleBracketState == AS_ATT_SEQ_OUTSIDE) { // bump stack up, and then back. txp.istack++; txp.startElementAttributesHandled(name, true); txp.istack--; txp.endElementAttributesHandled(name); mAngleBracketState = AS_END_ELEMENT_EMITTED; } else if (mAngleBracketState == AS_COMMENT) ; else if (mAngleBracketState == AS_OUTSIDE) txp.characters("/"); else return "slash in brackets wrong"; break; case '>': if (mAngleBracketState == AS_END_ELEMENT_EMITTED) ; else if (mAngleBracketState == AS_ATT_SEQ_OUTSIDE) { txp.istack++; txp.startElementAttributesHandled(name, false); } else if (mAngleBracketState == AS_COMMENT) { if (!prevcommtoken.endsWith("--")) break; } else return "Angle Brackets mismatch on close"; mAngleBracketState = AS_OUTSIDE; break; case StreamTokenizer.TT_WORD: if (mAngleBracketState == AS_FIRST_OPEN) { if (st.sval.startsWith("!--")) { mAngleBracketState = AS_COMMENT; prevcommtoken = st.sval.substring(3); } else { // place on stack. txp.iposstack[txp.istack] = (txp.istack == 0 ? 0 : txp.iposstack[txp.istack - 1]); txp.elemstack[txp.istack] = st.sval; name = st.sval; mAngleBracketState = AS_ATT_SEQ_OUTSIDE; } } else if (mAngleBracketState == AS_ATT_SEQ_OUTSIDE) { attname = st.sval; mAngleBracketState = AS_ATT_SEQ_EQ; } else if (mAngleBracketState == AS_END_ELEMENT_SLASH) { name = st.sval; txp.istack--; if (txp.istack == -1) return "too many end elements"; if (!name.equals(txp.elemstack[txp.istack])) return "mismatch of end element " + name + "!=" + txp.elemstack[txp.istack]; txp.endElementAttributesHandled(name); mAngleBracketState = AS_END_ELEMENT_EMITTED; } else if (mAngleBracketState == AS_QM_HEADER) ; else if (mAngleBracketState == AS_OUTSIDE) txp.characters(st.sval); else if (mAngleBracketState == AS_COMMENT) prevcommtoken = st.sval; else return "Unknown word state"; break; case '=': if (mAngleBracketState == AS_ATT_SEQ_EQ) mAngleBracketState = AS_ATT_SEQ_SET; else if (mAngleBracketState == AS_QM_HEADER) ; else if (mAngleBracketState == AS_COMMENT) ; else if (mAngleBracketState == AS_OUTSIDE) txp.characters("="); else return "Misplaced = in attribute"; break; case '"': if (mAngleBracketState == AS_ATT_SEQ_SET) { // place on stack. txp.attnamestack[txp.iposstack[txp.istack]] = attname; txp.attvalstack[txp.iposstack[txp.istack]] = TNXML.xunmanglxmltext(st.sval); txp.iposstack[txp.istack]++; mAngleBracketState = AS_ATT_SEQ_OUTSIDE; } else if (mAngleBracketState == AS_QM_HEADER) ; else if (mAngleBracketState == AS_COMMENT) ; else return "Bad value (missing quotes) in attribute"; break; default: if (mAngleBracketState == AS_OUTSIDE) { System.out.println("making default case chars " + (char)st.ttype); txp.characters(String.valueOf((char)st.ttype)); } else if (mAngleBracketState == AS_COMMENT) ; else if (mAngleBracketState == AS_QM_HEADER) ; else return "Unknown word state " + st.ttype; break; } } return null; } }; tunnelx-20140102.orig/src/SurvexLoaderNew.java0000644000000000000000000005352212261213471016024 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2008 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.io.IOException; import java.io.FileNotFoundException; import java.util.Arrays; import java.util.List; import java.util.ArrayList; import java.util.Stack; import java.util.Collections; import java.util.Collection; import java.util.Map; import java.util.HashMap; import java.util.Set; import java.util.HashSet; // // // SurvexLoaderNew // // ///////////////////////////////////////////// ///////////////////////////////////////////// class SVXline { String cmd; String sline; String comment; ///////////////////////////////////////////// SVXline(String lcmd, String lsline, String lcomment) { cmd = lcmd; sline = lsline; comment = lcomment; } ///////////////////////////////////////////// boolean IsCalibration() { if (cmd == null) return false; return ("*calibrate".equals(cmd) || "*units".equals(cmd) || "*date".equals(cmd) || "*team".equals(cmd)); } ///////////////////////////////////////////// public String toString() { if (cmd == null) { if (comment == null) return sline; return sline + comment; } if (comment == null) return cmd + " " + sline; return cmd + " " + sline + comment; } ///////////////////////////////////////////// SVXline(String lsline) { sline = lsline.trim(); // comment should chew up previous whitespace int ic = sline.indexOf(";"); if (ic != -1) { while ((ic > 0) && (sline.charAt(ic - 1) <= '\u0020')) ic--; comment = sline.substring(ic); sline = sline.substring(0, ic); } else comment = null; if ((sline.length() != 0) && (sline.charAt(0) == '*')) { int ie = 0; while (ie < sline.length()) { if (sline.charAt(ie) <= '\u0020') break; ie++; } cmd = sline.substring(0, ie).toLowerCase(); sline = sline.substring(ie).trim(); sline = sline.replace("\"", ""); } else cmd = null; } } ///////////////////////////////////////////// ///////////////////////////////////////////// class SurvexLoaderNew { Map > eqmap = null; Map > eqlmap = null; // used for interpreting svx text List vlegs = null; List vfixes = null; Vec3 avgfix; Map osmap = null; Vec3d sketchLocOffset; Stack statrec = null; int npieces = 0; int nstationsdone = 0; // allow for loading the centreline as an elevation // ;IMPORT_AS_ELEVATION 90 boolean bprojectedelevation = false; float projectedelevationvalue = 0.0F; boolean btopextendedelevation = false; ///////////////////////////////////////////// public SurvexLoaderNew() { } ///////////////////////////////////////////// void DumpEQs() { List< Set > Dss = new ArrayList< Set >(); for (Set lss : eqmap.values()) { if (!Dss.contains(lss)) System.out.println("PPP: " + lss); Dss.add(lss); } } ///////////////////////////////////////////// void AddEquate(String prefixd, String sline) { //System.out.println("EQQ: " + svxbatch.prefix + " " + svxline.sline); Set v0 = null; for (String eqel : sline.split("\\s+")) { String peqel = prefixd + eqel.toLowerCase(); if (v0 != null) { Set v = eqmap.get(peqel); if (v != null) { v0.addAll(v); for (String p : v) eqmap.put(p, v0); } else { v0.add(peqel); eqmap.put(peqel, v0); } } else { v0 = eqmap.get(peqel); if (v0 == null) { v0 = new HashSet(); v0.add(peqel); eqmap.put(peqel, v0); } } // put the mapping into the SVXbatch prefix if (eqlmap != null) { int lld = peqel.lastIndexOf('.'); String lprefixd = peqel.substring(0, lld + 1).toLowerCase(); Set vel = eqlmap.get(lprefixd); if (vel == null) { vel = new HashSet(); eqlmap.put(lprefixd, vel); } vel.add(peqel); } } } ///////////////////////////////////////////// void ReadSurvexRecurseIncludeOnly(StringBuilder sb, FileAbstraction loadfile) throws IOException { LineInputStream lis = new LineInputStream(loadfile.GetInputStream(), loadfile, null, null); while (lis.FetchNextLineNoSplit()) { String sline = lis.GetLine(); if (sline.matches("(?i)\\s*\\*include\\s.*")) { SVXline svxline = new SVXline(sline); assert "*include".equals(svxline.cmd); FileAbstraction includefile = FileAbstraction.calcIncludeFile(loadfile, svxline.sline, false); sb.append(TN.nl); sb.append(" ;;;;;;;;;;;;;;;;;;;;;;;;;;;"); sb.append(TN.nl); sb.append(" ; included file \""); sb.append(svxline.sline); sb.append("\""); if (svxline.comment != null) sb.append(svxline.comment); sb.append(TN.nl); sb.append(" ;;;;;;;;;;;;;;;;;;;;;;;;;;;"); sb.append(TN.nl); ReadSurvexRecurseIncludeOnly(sb, includefile); sb.append(" ; end-included file \""); sb.append(svxline.sline); sb.append("\""); sb.append(TN.nl); sb.append(TN.nl); } else { sb.append(sline); sb.append(TN.nl); } } lis.inputstream.close(); } ///////////////////////////////////////////// public String LoadSVX(FileAbstraction loadfile) { StringBuilder sb = new StringBuilder(); try { ReadSurvexRecurseIncludeOnly(sb, loadfile); } catch (IOException e) { TN.emitError(e.toString()); }; return sb.toString(); } ///////////////////////////////////////////// // pulls stuff into vlegs void InterpretSvxTextRecurse(String prefixd, LineInputStream lis, LegLineFormat initLLF, int depth) { // make working copy (will be from new once the header is right). LegLineFormat CurrentLegLineFormat = new LegLineFormat(initLLF); while (lis.FetchNextLine()) { // concatennate case when there is a space after the * if (lis.w[0].equals("*") && (lis.iwc >= 2)) { lis.w[0] = lis.w[0] + lis.w[1]; for (int i = 2; i < lis.iwc; i++) lis.w[i - 1] = lis.w[i]; lis.w[lis.iwc - 1] = ""; lis.iwc--; } if (lis.w[0].equals("")) { // magic code which we can stick at the start to cause the centreline to be converted to a projected elevation if (lis.comment.trim().startsWith("IMPORT_AS_ELEVATION")) { projectedelevationvalue = Float.valueOf(lis.comment.trim().substring(19).trim()); bprojectedelevation = true; } } else if (lis.w[0].equalsIgnoreCase("*calibrate")) CurrentLegLineFormat.StarCalibrate(lis.w[1], lis.w[2], lis.w[3], lis); else if (lis.w[0].equalsIgnoreCase("*units")) { int ist = 2; while (lis.w[ist].equalsIgnoreCase("dx") || lis.w[ist].equalsIgnoreCase("dy") || lis.w[ist].equalsIgnoreCase("dz") || lis.w[ist].equalsIgnoreCase("compass") || lis.w[ist].equalsIgnoreCase("backcompass") || lis.w[ist].equalsIgnoreCase("clino") || lis.w[ist].equalsIgnoreCase("backclino")) ist++; for (int iist = 1; iist < ist; iist++) CurrentLegLineFormat.StarUnits(lis.w[iist], lis.w[ist], lis.w[ist + 1], lis); } else if (lis.w[0].equalsIgnoreCase("*set")) CurrentLegLineFormat.StarSet(lis.w[1], lis.w[2], lis); else if (lis.w[0].equalsIgnoreCase("*data")) { if (!CurrentLegLineFormat.StarDataNormal(lis.w, lis.iwc)) TN.emitWarning("Bad *data line: " + lis.GetLine()); } else if (lis.w[0].equalsIgnoreCase("*fix")) { OneLeg oleg = CurrentLegLineFormat.ReadFix(lis.w, lis); if (oleg != null) { oleg.stto = prefixd + oleg.stto.toLowerCase(); vfixes.add(oleg); } } else if (lis.w[0].equalsIgnoreCase("*date")) CurrentLegLineFormat.bb_svxdate = lis.w[1]; else if (lis.w[0].equalsIgnoreCase("*title")) CurrentLegLineFormat.bb_svxtitle = lis.w[1]; else if (lis.w[0].equalsIgnoreCase("*flags")) CurrentLegLineFormat.StarFlags(lis.w, lis.iwc); else if (lis.w[0].equalsIgnoreCase("*team")) { if (lis.w[1].equalsIgnoreCase("notes")) CurrentLegLineFormat.bb_teamnotes = lis.remainder2.trim(); else if (lis.w[1].equalsIgnoreCase("tape")) CurrentLegLineFormat.bb_teamtape = lis.remainder2.trim(); else if (lis.w[1].equalsIgnoreCase("insts")) CurrentLegLineFormat.bb_teaminsts = lis.remainder2.trim(); else if (lis.w[1].equalsIgnoreCase("pics")) CurrentLegLineFormat.bb_teampics = lis.remainder2.trim(); else ; // TN.emitMessage("Unknown *team " + lis.remainder1); CurrentLegLineFormat.UpdateTotalTeam(); } else if (lis.w[0].equalsIgnoreCase("*begin")) { String nprefixd; if (lis.w[1].toLowerCase().equals("")) { // no longer an issue due to ignoring structure now // all we need to maintain track of really are flags surface //TN.emitMessage("empty *begin in " + prefixd); nprefixd = prefixd; } else nprefixd = prefixd + lis.w[1].toLowerCase() + "."; InterpretSvxTextRecurse(nprefixd, lis, CurrentLegLineFormat, depth + 1); // recurse down } else if (lis.w[0].equalsIgnoreCase("*end")) { if (depth == 0) TN.emitWarning("Too many *ends for the *begin blocks"); return; // out of recursion } else if (lis.w[0].equalsIgnoreCase("*include")) TN.emitWarning("word should have been stripped"); else if (lis.w[0].equalsIgnoreCase("*entrance")) ; // ignore. else if (lis.w[0].equalsIgnoreCase("*instrument")) ; // ignore. else if (lis.w[0].equalsIgnoreCase("*export")) ; // ignore. else if (lis.w[0].equalsIgnoreCase("*equate")) { SVXline svxline = new SVXline(lis.GetLine()); AddEquate(prefixd, svxline.sline); } else if (lis.w[0].equalsIgnoreCase("*sd")) ; // ignore. else if (lis.w[0].startsWith("*")) TN.emitWarning("Unknown command: " + lis.w[0]); // used to be ==2. want to use the ignoreall term in the *data normal... else if ((lis.iwc >= 2) || ((CurrentLegLineFormat.newlineindex != -1) && (lis.iwc >= 1))) { OneLeg oleg = CurrentLegLineFormat.ReadLeg(lis.w, lis); if (oleg != null) { if (oleg.stfrom != null) oleg.stfrom = prefixd + oleg.stfrom.toLowerCase(); oleg.stto = prefixd + oleg.stto.toLowerCase(); vlegs.add(oleg); } } else TN.emitWarning("Too few arguments: " + lis.GetLine()); } if (depth != 0) TN.emitWarning("Data ended with *begin blocks still open"); } ///////////////////////////////////////////// void InterpretSvxText(String svxtext) { vlegs = new ArrayList(); vfixes = new ArrayList(); osmap = new HashMap(); eqmap = new HashMap >(); LineInputStream lis = new LineInputStream(svxtext, null); LegLineFormat llf = new LegLineFormat(); llf.btopextendedelevation = btopextendedelevation; InterpretSvxTextRecurse("", lis, llf, 0); avgfix = new Vec3(0.0F, 0.0F, 0.0F); for (OneLeg ol : vfixes) avgfix.PlusEquals(ol.mlegvec); if (vfixes.size() != 0) avgfix.TimesEquals(1.0F / vfixes.size()); // group the equates into the map for (Set vs : eqmap.values()) { String osn = Collections.min(vs); OneStation osc = new OneStation(osn); for (String s : vs) osmap.put(s, osc); } // put the station objects into the legs for (OneLeg ol : vlegs) { if (ol.stfrom != null) { String lstfrom = ol.stfrom.toLowerCase(); ol.osfrom = osmap.get(lstfrom); if (ol.osfrom == null) { ol.osfrom = new OneStation(ol.stfrom); osmap.put(lstfrom, ol.osfrom); } } String lstto = ol.stto.toLowerCase(); ol.osto = osmap.get(lstto); if (ol.osto == null) { ol.osto = new OneStation(ol.stto); osmap.put(lstto, ol.osto); } } // put station object in the fixes for (OneLeg olf : vfixes) { assert (olf.stfrom == null); String lstto = olf.stto.toLowerCase(); olf.osto = osmap.get(lstto); if (olf.osto == null) { olf.osto = new OneStation(olf.stto); osmap.put(lstto, olf.osto); } } System.out.println("Num Legs: " + vlegs.size() + " EQQ: " + eqmap.size() + " SS: " + osmap.values().size() + " " + avgfix.toString()); } ///////////////////////////////////////////// class posentry extends Vec3d { String sname; posentry(String[] w) { assert (w.length == 5) && w[0].equals(""); sname = w[4]; x = Double.parseDouble(w[1]); y = Double.parseDouble(w[2]); z = Double.parseDouble(w[3]); } } ///////////////////////////////////////////// boolean LoadPosFile(LineInputStream lis, Vec3 appsketchLocOffset) throws IOException { lis.FetchNextLineNoSplit(); System.out.println("POSLINE0: " + lis.GetLine()); // ( -19.97, -0.88, -64.00 ) 204.110_bidet.1 // load all the stations first so we can average them sketchLocOffset = (appsketchLocOffset == null ? new Vec3d(0.0, 0.0, 0.0) : new Vec3d(appsketchLocOffset.x, appsketchLocOffset.y, appsketchLocOffset.z)); List posentries = new ArrayList(); while (lis.FetchNextLineNoSplit()) { String[] w = lis.GetLine().split("[\\s,()]+"); posentry pe = new posentry(w); posentries.add(pe); if (appsketchLocOffset == null) sketchLocOffset.PlusEquals(pe); } if ((posentries.size() != 0) && (appsketchLocOffset == null)) sketchLocOffset.TimesEquals(1.0 / posentries.size()); for (posentry pe : posentries) { OneStation os = osmap.get(pe.sname); if (os != null) { if (os.Loc == null) os.Loc = new Vec3((float)(pe.x - sketchLocOffset.x), (float)(pe.y - sketchLocOffset.y), (float)(pe.z - sketchLocOffset.z)); else //System.out.println("DUP: " + pe.sname + ": " + Math.abs(os.Loc.x + sketchLocOffset.x - pe.x) + " " + Math.abs(os.Loc.y + sketchLocOffset.y - pe.y) + " " + Math.abs(os.Loc.z + sketchLocOffset.z - pe.z)); assert (Math.abs(os.Loc.x + sketchLocOffset.x - pe.x) <= 0.01) && (Math.abs(os.Loc.y + sketchLocOffset.y - pe.y) <= 0.01) && (Math.abs(os.Loc.z + sketchLocOffset.z - pe.z) <= 0.01); } else TN.emitWarning("unable to match pos station: " + pe.sname); // might be a naked fix } for (OneStation os : osmap.values()) if (os.Loc == null) TN.emitWarning("** Station not POS applied: " + os.name); for (OneStation os : osmap.values()) { if (os.Loc == null) return !TN.emitWarning("Station not POS applied: " + os.name); } return true; } // range values of the box (used for perspective projections float volxlo, volxhi; float volylo, volyhi; float volzlo, volzhi; ///////////////////////////////////////////// boolean MergeVol(float x, float y, float z, boolean bFirst) { //System.out.println(" x=" + x + " y=" + y + " z=" + z + " " + bFirst); if (bFirst || (x < volxlo)) volxlo = x; if (bFirst || (x > volxhi)) volxhi = x; if (bFirst || (y < volylo)) volylo = y; if (bFirst || (y > volyhi)) volyhi = y; if (bFirst || (z < volzlo)) volzlo = z; if (bFirst || (z > volzhi)) volzhi = z; return false; } ///////////////////////////////////////////// Vec3 GoLeg(Vec3 vf, OneLeg ol, int sign) { if (!btopextendedelevation) return new Vec3(vf.x + ol.mlegvec.x * sign, vf.y + ol.mlegvec.y * sign, vf.z + ol.mlegvec.z * sign); int xsign = (ol.btopextendedelevationflip ? -1 : 1); return new Vec3(vf.x + ol.mlegvec.x * xsign, vf.y + ol.mlegvec.y * sign, vf.z + ol.mlegvec.z * sign); } ///////////////////////////////////////////// void CalcPosStack() { while (!statrec.isEmpty()) { OneStation os = statrec.pop(); for (OneLeg ol : os.olconn) { if (ol.bnosurvey) continue; if ((os == ol.osfrom) && (ol.osto.Loc == null)) { nstationsdone++; OneStation osn = ol.osto; osn.Loc = GoLeg(os.Loc, ol, +1); statrec.push(osn); } if ((os == ol.osto) && (ol.osfrom.Loc == null)) { nstationsdone++; OneStation osn = ol.osfrom; osn.Loc = GoLeg(os.Loc, ol, -1); statrec.push(osn); } } } } ///////////////////////////////////////////// int CalcStationPositions() { // build up the network of stations int npieces = 0; int nfixpieces = 0; statrec = new Stack(); for (OneLeg ol : vlegs) { ol.osfrom.olconn.add(ol); ol.osto.olconn.add(ol); } for (OneLeg olf : vfixes) { if ((olf.osto != null) && (olf.osto.Loc == null)) { olf.osto.Loc = new Vec3((float)(olf.mlegvec.x - sketchLocOffset.x), (float)(olf.mlegvec.y - sketchLocOffset.y), (float)(olf.mlegvec.z - sketchLocOffset.z)); statrec.push(olf.osto); nstationsdone++; } } if (!statrec.isEmpty()) { CalcPosStack(); npieces++; } for (OneLeg ol : vlegs) { if ((ol.osfrom != null) && (ol.osfrom.Loc == null)) { TN.emitWarning("making station calculations for a disconnected component of the survey at station "+ol.osfrom); ol.osfrom.Loc = new Vec3((float)npieces * 1000.0F, 0.0F, 0.0F); statrec.push(ol.osfrom); nstationsdone++; npieces++; CalcPosStack(); } } return npieces; } ///////////////////////////////////////////// void ConstructWireframe(List lvlegs, List lvstations) { lvlegs.addAll(vlegs); Set sstations = new HashSet(); sstations.addAll(osmap.values()); lvstations.addAll(sstations); // make the bounding box values, just containing the real legs boolean bFirst = true; for (OneStation os : sstations) { if (os.Loc != null) bFirst = MergeVol(os.Loc.x, os.Loc.y, os.Loc.z, bFirst); else System.out.println("SST missing: " + os.name); } System.out.println("Volume range [" + volxlo + ", " + volxhi + "] [" + volylo + ", " + volyhi + "] [" + (volzlo) + ", " + volzhi + "]"); } ///////////////////////////////////////////// ///////////////////////////////////////////// // this is where we match the positions and discard vlegs already accounted for boolean ThinDuplicateLegs(List vnodes, List vpaths) { Map cnodemaps = new HashMap(); for (OnePathNode opn : vnodes) { if (opn.IsCentrelineNode()) cnodemaps.put(opn.pnstationlabel, opn); } if (cnodemaps.isEmpty()) return true; float tol = 0.01F; List lvlegs = vlegs; vlegs = new ArrayList(); for (OneLeg ol : lvlegs) { if (ol.osfrom == null) continue; OnePathNode eopnfrom = cnodemaps.get(ol.osfrom.name); OnePathNode eopnto = cnodemaps.get(ol.osto.name); if (eopnfrom != null) { System.out.println(" " + Math.abs(ol.osfrom.station_opn.pn.getX() - eopnfrom.pn.getX()) + " " + Math.abs(ol.osfrom.station_opn.pn.getY() - eopnfrom.pn.getY()) + " " + Math.abs(ol.osfrom.station_opn.zalt - eopnfrom.zalt)); if ((Math.abs(ol.osfrom.station_opn.pn.getX() - eopnfrom.pn.getX()) > tol) || (Math.abs(ol.osfrom.station_opn.pn.getY() - eopnfrom.pn.getY()) > tol) || (Math.abs(ol.osfrom.station_opn.zalt - eopnfrom.zalt) > tol)) return false; ol.osfrom.station_opn = eopnfrom; } if (eopnto != null) { System.out.println(" t " + Math.abs(ol.osto.station_opn.pn.getX() - eopnto.pn.getX()) + " " + Math.abs(ol.osto.station_opn.pn.getY() - eopnto.pn.getY()) + " " + Math.abs(ol.osto.station_opn.zalt - eopnto.zalt)); if ((Math.abs(ol.osto.station_opn.pn.getX() - eopnto.pn.getX()) > tol) || (Math.abs(ol.osto.station_opn.pn.getY() - eopnto.pn.getY()) > tol) || (Math.abs(ol.osto.station_opn.zalt - eopnto.zalt) > tol)) return false; ol.osto.station_opn = eopnto; } if ((eopnfrom == null) || (eopnto == null)) // || the nodes exist, but there's no corresponding leg in the list vlegs.add(ol); } return true; } static int DDD = 3; ///////////////////////////////////////////// String FindStationTitle(OnePath op) { //String lpnlabtail = op.plabedl.centrelinetail.replaceAll("[|^]", "."); //String lpnlabhead = op.plabedl.centrelinehead.replaceAll("[|^]", "."); String lpnlabtail = (op.pnstart != null ? op.pnstart.pnstationlabel.replaceAll("[|^]", ".") : ""); // this has had null; don't know how. String lpnlabhead = (op.pnend != null ? op.pnend.pnstationlabel.replaceAll("[|^]", ".") : ""); if (op.pnend == null) System.out.println("FSSSST nll " + lpnlabtail); String res1 = null; for (OneLeg ol : vlegs) { // I don't know if we're doing all the equates properly here // op.plabedl.centrelinetail op.plabedl.centrelinehead but with [|^] converted to . if ((ol.stfrom != null) && !ol.svxtitle.equals("")) { boolean bfrom = ol.osfrom.name.equalsIgnoreCase(lpnlabtail); boolean bto = ol.osto.name.equalsIgnoreCase(lpnlabhead); if (bfrom && bto) return ol.svxtitle; if (bfrom || bto) res1 = ol.svxtitle; // captures one end } } /* System.out.println("Failed to match up " + lpnlabtail + " -- " + lpnlabhead); System.out.println("\n****"); System.out.println(res1); for (OneLeg ol : vlegs) { if (ol.stfrom != null) System.out.println(" " + ol.osfrom.name + " " + ol.osto.name); } //if (DDD-- < 0) System.exit(0); */ return res1; } } tunnelx-20140102.orig/src/OneStation.java0000644000000000000000000000575412261213471015016 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.Graphics; import java.util.List; import java.util.ArrayList; // // // OneStation // // class OneStation { // unique identifier public String name; // location and flag used to set the location Vec3 Loc = null; Vec3 tLoc = new Vec3(); // used to give the index for vrml, and for cross sections in whole survey mode. int vsig; // transformed for viewing points public int TLocX = 0; public int TLocY = 0; public int TLocZ = 0; // connections to other legs List olconn = new ArrayList(); // position set for calculating location boolean bPositionSet = false; OnePathNode station_opn = null; // used in the ImportCentrelineLabel routine ///////////////////////////////////////////// public OneStation(String lname) { name = lname; vsig = -1; if (name.indexOf("..") != -1) TN.emitError("ashas " + lname); } ///////////////////////////////////////////// float AngDiff(float ang) { if (ang < 0.0F) ang += 360.0F; if (ang > 360.0F) ang -= 360.0F; return Math.min(ang, 360.0F - ang); } ///////////////////////////////////////////// // transformed for viewing points void SetTLoc(Matrix3D mat) { tLoc.x = Loc.x * mat.xx + Loc.y * mat.xy + Loc.z * mat.xz + mat.xo; tLoc.y = Loc.x * mat.yx + Loc.y * mat.yy + Loc.z * mat.yz + mat.yo; tLoc.z = Loc.x * mat.zx + Loc.y * mat.zy + Loc.z * mat.zz + mat.zo; TLocX = (int)tLoc.x; TLocY = (int)tLoc.y; TLocZ = (int)tLoc.z; } ///////////////////////////////////////////// int sqDist(int mx, int my) { int dx = TLocX - mx; int dy = TLocY - my; return dx * dx + dy * dy; } ///////////////////////////////////////////// // used in wireframe graphics. void paintW(Graphics g, boolean bActive, boolean bLong) { g.setColor(bActive ? TN.wfmpointActive : TN.wfmpointInactive); g.drawRect(TLocX - TN.xsgPointSize, TLocY - TN.xsgPointSize, 2 * TN.xsgPointSize, 2 * TN.xsgPointSize); g.setColor(bActive ? TN.wfmnameActive : TN.wfmnameInactive); g.drawString(name, TLocX + TN.xsgPointSize * 2, TLocY + TN.xsgPointSize * 2); } } tunnelx-20140102.orig/src/SketchBackgroundPanel.java0000644000000000000000000003724412261213471017133 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2004 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import javax.swing.JPanel; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JRadioButton; import javax.swing.ButtonGroup; import javax.swing.JTextField; import javax.swing.JTextArea; import javax.swing.JLabel; import javax.swing.JComboBox; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.awt.geom.Point2D; import java.util.List; import java.util.ArrayList; ///////////////////////////////////////////// class SketchBackgroundPanel extends JPanel { SketchDisplay sketchdisplay; JCheckBox cbshowbackground; JCheckBox cbshowgrid; JCheckBox cbsnaptogrid; // tells us the grid spacing. JTextField tfgridspacing = new JTextField(""); int gsoffset = 0; JComboBox cbbackimage = new JComboBox(); List tsvpathsframescbelements = new ArrayList(); // parallel to the list List tsvpathsframescbelementsS = new ArrayList(); // parallel to the list; used to prevent multiple equal strings getting into the combobox, which prevents it working; // the correct implementation would have been to add OnePaths into the combobox and apply the toString function to get the names ///////////////////////////////////////////// ActionListener cbbackimageAL = new ActionListener() { public void actionPerformed(ActionEvent event) { System.out.println("cbbackimageSEL " + cbbackimage.getSelectedIndex() + " " + event.getActionCommand()); int i = cbbackimage.getSelectedIndex(); if (i != -1) { OnePath op = tsvpathsframescbelements.get(i); if (op.IsSketchFrameConnective()) { sketchdisplay.sketchlinestyle.pthstyleareasigtab.LoadSketchFrameDef(op.plabedl.sketchframedef, false); if (!op.plabedl.sketchframedef.sfsketch.equals("")) { sketchdisplay.sketchgraphicspanel.tsketch.opframebackgrounddrag = op; sketchdisplay.sketchlinestyle.pthstyleareasigtab.UpdateSFView(op, false); } else sketchdisplay.sketchgraphicspanel.SelectSingle(op); // select it for the subset kind } else { assert op.IsSurvexLabel(); sketchdisplay.sketchgraphicspanel.SelectSingle(op); // select it for the subset kind //sketchdisplay.ImportCentrelineLabel(true); // this causes a crash } } } }; ///////////////////////////////////////////// class radbuttpress implements ActionListener { int lgsoffset; radbuttpress(int llgsoffset) { lgsoffset = llgsoffset; } public void actionPerformed(ActionEvent event) { gsoffset = lgsoffset; sketchdisplay.sketchgraphicspanel.RedoBackgroundView(); } }; ///////////////////////////////////////////// void SetGridOrigin(boolean btocurrent) { if (btocurrent) { if (sketchdisplay.sketchgraphicspanel.currgenpath != null) { Point2D pn = sketchdisplay.sketchgraphicspanel.currgenpath.pnstart.pn; sketchdisplay.sketchgraphicspanel.sketchgrid.txorig = (float)pn.getX(); sketchdisplay.sketchgraphicspanel.sketchgrid.tyorig = (float)pn.getY(); } } else { sketchdisplay.sketchgraphicspanel.sketchgrid.txorig = sketchdisplay.sketchgraphicspanel.sketchgrid.xorig; sketchdisplay.sketchgraphicspanel.sketchgrid.tyorig = sketchdisplay.sketchgraphicspanel.sketchgrid.yorig; } sketchdisplay.sketchgraphicspanel.RedoBackgroundView(); } ///////////////////////////////////////////// boolean UploadBackgroundFile() { OnePath op = sketchdisplay.sketchgraphicspanel.tsketch.opframebackgrounddrag; if (op == null) return TN.emitWarning("Must have background image visible"); if (op.plabedl.sketchframedef.pframeimage != null) { String filename = op.plabedl.sketchframedef.sfsketch; filename = filename.replace("\\", "|"); filename = filename.replace("/", "|"); System.out.println("TO uploadedfile " + filename); String target = TN.troggleurl + "jgtuploadfile"; // for now FileAbstraction uploadedfile = NetConnection.uploadFile(FileAbstraction.MakeOpenableFileAbstraction(target), "backgroundimage", filename, op.plabedl.sketchframedef.pframeimage.GetImage(true), null); System.out.println("uploadedfile " + uploadedfile); if (uploadedfile.localurl != null) { op.plabedl.sketchframedef.sfsketch = uploadedfile.getPath(); op.plabedl.sketchframedef.SetSketchFrameFiller(sketchdisplay.mainbox, sketchdisplay.sketchgraphicspanel.tsketch.realposterpaperscale, sketchdisplay.sketchgraphicspanel.tsketch.sketchLocOffset, sketchdisplay.sketchgraphicspanel.tsketch.sketchfile); if (op == sketchdisplay.sketchgraphicspanel.currgenpath) sketchdisplay.sketchlinestyle.pthstyleareasigtab.UpdateSFView(op, true); UpdateBackimageCombobox(55); // magic number forces update of dropdown box sketchdisplay.sketchgraphicspanel.RedrawBackgroundView(); } } return true; } ///////////////////////////////////////////// void NewBackgroundFile() { TN.emitMessage("calling NewBackgroundFile " + sketchdisplay.sketchgraphicspanel.tsketch.sketchfile); SvxFileDialog sfiledialog = SvxFileDialog.showOpenDialog(TN.currentDirectoryIMG, sketchdisplay, SvxFileDialog.FT_BITMAP, false); if ((sfiledialog == null) || (sfiledialog.svxfile == null)) return; String imfilename = null; if (sfiledialog.svxfile.localfile != null) { TN.currentDirectoryIMG = sfiledialog.svxfile; try { imfilename = FileAbstraction.GetImageFileName(sketchdisplay.sketchgraphicspanel.tsketch.sketchfile.getParentFile(), sfiledialog.svxfile); } catch (IOException ie) { ie.printStackTrace(); TN.emitWarning(ie.toString()); }; } else if (sfiledialog.svxfile.localurl != null) { try { //imfilename = sfiledialog.svxfile.localurl.toString(); imfilename = FileAbstraction.GetImageFileName(sketchdisplay.sketchgraphicspanel.tsketch.sketchfile, sfiledialog.svxfile); } catch (IOException ie) { ie.printStackTrace(); TN.emitWarning(ie.toString()); }; } if (imfilename == null) return; OnePath prevcurrpath = sketchdisplay.sketchgraphicspanel.currgenpath; sketchdisplay.sketchgraphicspanel.ClearSelection(true); sketchdisplay.sketchgraphicspanel.repaint(); System.out.println("YYYYY " + imfilename); OnePath gop = sketchdisplay.sketchgraphicspanel.MakeConnectiveLineForData(0, 1.0F); // this is made temporarily to hold the sketchframedef on //sketchdisplay.sketchgraphicspanel.RedrawBackgroundView(); gop.plabedl.sketchframedef.sfsketch = imfilename; gop.plabedl.sketchframedef.sfscaledown = 1.0F; gop.plabedl.sketchframedef.sfrotatedeg = 0.0F; gop.plabedl.sketchframedef.sfxtrans = (sketchdisplay.sketchgraphicspanel.tsketch.sketchLocOffset.x / TN.CENTRELINE_MAGNIFICATION); gop.plabedl.sketchframedef.sfytrans = -(sketchdisplay.sketchgraphicspanel.tsketch.sketchLocOffset.y / TN.CENTRELINE_MAGNIFICATION); gop.plabedl.sketchframedef.SetSketchFrameFiller(sketchdisplay.mainbox, sketchdisplay.sketchgraphicspanel.tsketch.realposterpaperscale, sketchdisplay.sketchgraphicspanel.tsketch.sketchLocOffset, sketchdisplay.sketchgraphicspanel.tsketch.sketchfile); sketchdisplay.sketchlinestyle.pthstyleareasigtab.UpdateSFView(gop, true); sketchdisplay.sketchgraphicspanel.tsketch.opframebackgrounddrag = gop; gop.plabedl.sketchframedef.MaxCentreOnScreenButt(sketchdisplay.sketchgraphicspanel.getSize(), true, 1.0, sketchdisplay.sketchgraphicspanel.tsketch.sketchLocOffset, sketchdisplay.sketchgraphicspanel.currtrans); sketchdisplay.sketchlinestyle.pthstyleareasigtab.UpdateSFView(gop, true); OnePath ggop = gop.plabedl.sketchframedef.MakeBackgroundOutline(1.0, sketchdisplay.sketchgraphicspanel.tsketch.sketchLocOffset); ggop.CopyPathAttributes(gop); assert ggop.plabedl.sketchframedef.IsImageType(); List pthstoadd = new ArrayList(); pthstoadd.add(ggop); sketchdisplay.sketchgraphicspanel.CommitPathChanges(null, pthstoadd); // sketchdisplay.sketchgraphicspanel.FrameBackgroundOutline(null); sketchdisplay.sketchgraphicspanel.tsketch.opframebackgrounddrag = ggop; sketchdisplay.sketchlinestyle.pthstyleareasigtab.UpdateSFView(ggop, true); if (sketchdisplay.bottabbedpane.getSelectedIndex() == 1) UpdateBackimageCombobox(4); if (!sketchdisplay.miShowBackground.isSelected()) sketchdisplay.miShowBackground.doClick(); sketchdisplay.sketchgraphicspanel.RedrawBackgroundView(); } ///////////////////////////////////////////// // with this case we're removing the action listener to avoid any events firing that are not from mouse clicks synchronized void UpdateBackimageCombobox(int iy) // the iy does nothing -- just for debug printing { OnePath tsvpathsframescbelementssel = sketchdisplay.sketchgraphicspanel.tsketch.opframebackgrounddrag; List ltsvpathsframescbelements = sketchdisplay.sketchgraphicspanel.tsvpathsframesall; boolean baddselelement = ((tsvpathsframescbelementssel != null) && !ltsvpathsframescbelements.contains(tsvpathsframescbelementssel)); // check if the values have changed assert tsvpathsframescbelements.size() == cbbackimage.getItemCount(); boolean btoupdate = (tsvpathsframescbelements.size() != ltsvpathsframescbelements.size() + (baddselelement ? 1 : 0)); if (iy == 55) btoupdate = true; int isel = -1; if (!btoupdate) { for (int i = 0; i < ltsvpathsframescbelements.size(); i++) { if (tsvpathsframescbelements.get(i) != ltsvpathsframescbelements.get(i)) { btoupdate = true; break; } if (tsvpathsframescbelements.get(i) == tsvpathsframescbelementssel) isel = i; } if (baddselelement && !btoupdate) { if (tsvpathsframescbelements.get(ltsvpathsframescbelements.size()) != tsvpathsframescbelementssel) btoupdate = true; else isel = ltsvpathsframescbelements.size(); } } if (btoupdate) { tsvpathsframescbelements.clear(); tsvpathsframescbelements.addAll(ltsvpathsframescbelements); if (baddselelement) tsvpathsframescbelements.add(tsvpathsframescbelementssel); // create distinct strings tsvpathsframescbelementsS.clear(); for (OnePath op : tsvpathsframescbelements) { String ssval; if (op.IsSketchFrameConnective()) { if (!op.plabedl.sketchframedef.sfsketch.equals("")) ssval = TN.shortenString(op.plabedl.sketchframedef.sfsketch, 35); else ssval = "Subset colours " + op.plabedl.sketchframedef.submapping.size(); } else { assert op.IsSurvexLabel(); ssval = "Survex label"; } int i = 1; String lssval = ssval; while (tsvpathsframescbelementsS.contains(lssval)) lssval = ssval + " (" + (++i) + ")"; tsvpathsframescbelementsS.add(lssval); } assert tsvpathsframescbelements.size() == tsvpathsframescbelementsS.size(); // suppress the action listener cbbackimage.removeActionListener(cbbackimageAL); cbbackimage.removeAllItems(); for (int i = 0; i < tsvpathsframescbelements.size(); i++) { // must give all entries different names because the implementation of setSelectedIndex is setSelectedItem cbbackimage.addItem(tsvpathsframescbelementsS.get(i)); if (tsvpathsframescbelements.get(i) == tsvpathsframescbelementssel) isel = i; } if (isel != cbbackimage.getSelectedIndex()) cbbackimage.setSelectedIndex(isel); cbbackimage.addActionListener(cbbackimageAL); } else if (isel != cbbackimage.getSelectedIndex()) { // suppress the action listener cbbackimage.removeActionListener(cbbackimageAL); cbbackimage.setSelectedIndex(isel); cbbackimage.addActionListener(cbbackimageAL); } assert (isel == -1 || (tsvpathsframescbelements.get(isel) == tsvpathsframescbelementssel)); assert isel == cbbackimage.getSelectedIndex(); } ///////////////////////////////////////////// SketchBackgroundPanel(SketchDisplay lsketchdisplay) { sketchdisplay = lsketchdisplay; // grid spacing controls JPanel pangridspacingc = new JPanel(new GridLayout(1, 0)); ButtonGroup buttgp = new ButtonGroup(); for (int i = -1; i <= 1; i++) { JRadioButton radbutt = new JRadioButton("", (i == 0)); radbutt.addActionListener(new radbuttpress(i)); buttgp.add(radbutt); pangridspacingc.add(radbutt); } tfgridspacing.setEditable(false); pangridspacingc.add(tfgridspacing); // impossible to get checkboxmenu items to reflect at these places (which would have been ideal) // maybe it should update the word on the button cbshowbackground = new JCheckBox("Show Background", true); cbshowbackground.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { if (sketchdisplay.miShowBackground.isSelected() != cbshowbackground.isSelected()) { sketchdisplay.miShowBackground.doClick(); } } } ); cbshowgrid = new JCheckBox("Show Grid", true); cbshowgrid.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { if (sketchdisplay.miShowGrid.isSelected() != cbshowgrid.isSelected()) { sketchdisplay.miShowGrid.doClick(); } } } ); cbsnaptogrid = new JCheckBox("Snap to Grid", false); cbsnaptogrid.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { if (sketchdisplay.miSnapToGrid.isSelected() != cbsnaptogrid.isSelected()) { sketchdisplay.miSnapToGrid.doClick(); } } } ); cbbackimage.addActionListener(cbbackimageAL); setLayout(new BorderLayout()); JPanel panupper = new JPanel(new BorderLayout()); JPanel panuppersec = new JPanel(new GridLayout(0, 2)); panuppersec.add(cbshowbackground); panuppersec.add(new JButton(sketchdisplay.acaAddImage)); panuppersec.add(new JButton(sketchdisplay.acaMoveBackground)); panuppersec.add(new JButton(sketchdisplay.acaReloadImage)); panupper.add(panuppersec, BorderLayout.NORTH); panupper.add(cbbackimage, BorderLayout.SOUTH); JPanel panlower = new JPanel(new GridLayout(0, 2)); panlower.add(cbsnaptogrid); panlower.add(cbshowgrid); panlower.add(new JLabel("Grid spacing (lo-hi)")); panlower.add(pangridspacingc); panlower.add(new JButton(sketchdisplay.acvSetGridOrig)); panlower.add(new JButton(sketchdisplay.acvResetGridOrig)); add(panupper, BorderLayout.NORTH); add(panlower, BorderLayout.SOUTH); } }; tunnelx-20140102.orig/src/SVGnew.java0000644000000000000000000001046112261213471014073 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2012 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.geom.Rectangle2D; import java.util.Map; import java.io.IOException; //////////////////////////////////////////////////////////////////////////////// class SVGnew { LineOutputStream los; boolean btransparentbackground; float scalefactor; int irenderingquality; Rectangle2D printrect; Map subsetattrstylesmap; //////////////////////////////////////////////////////////////////////////////// SVGnew(FileAbstraction fa, boolean lbtransparentbackground, float lscalefactor, Rectangle2D lprintrect, int lirenderingquality, Map lsubsetattrstylesmap) throws IOException { los = new LineOutputStream(fa, "UTF-8"); btransparentbackground = lbtransparentbackground; scalefactor = lscalefactor; printrect = lprintrect; irenderingquality = lirenderingquality; subsetattrstylesmap = lsubsetattrstylesmap; } void writeheader() throws IOException { TNXML.chconvleng = TNXML.chconvlengWSP; // a complete hack to stop &space; getting in here double widthmm = (printrect.getWidth() / TN.CENTRELINE_MAGNIFICATION) / scalefactor * 1000; double heightmm = (printrect.getHeight() / TN.CENTRELINE_MAGNIFICATION) / scalefactor * 1000; TN.emitMessage("Scalefactor " + scalefactor + " paperwidth="+widthmm +"mm paperheight="+heightmm +"mm"); los.WriteLine("\n"); los.WriteLine(""); String viewbox = "0 0 " + String.valueOf(printrect.getWidth()) + " " + String.valueOf(printrect.getHeight()); los.WriteLine(TNXML.xcomopen(0, "svg", "width", Double.toString(widthmm) + "mm", "height", Double.toString(heightmm) + "mm", "viewBox", viewbox, "version", "1.1", "xmlns", "http://www.w3.org/2000/svg", "xmlns:xlink", "http://www.w3.org/1999/xlink")); los.WriteLine(TNXML.xcomtext(1, "title", "Example")); los.WriteLine(TNXML.xcomtext(1, "desc", "description thing")); los.WriteLine(TNXML.xcom(1, "rect", "x", "0", "y", "0", "width", String.valueOf(printrect.getWidth()), "height", String.valueOf(printrect.getHeight()), "fill", "none", "stroke", "blue")); } ///////////////////////////////////////////// void writestyles() throws IOException { los.Write(TNXML.xcomopen(0, "style", "type", "text/css")); los.WriteLine(""); los.WriteLine(TNXML.xcomclose(0, "style")); } ///////////////////////////////////////////// void DrawSketch(OneSketch tsketch) throws IOException { writeheader(); los.WriteLine(TNXML.xcomopen(0, "defs")); writestyles(); los.WriteLine(TNXML.xcomopen(1, "g", "id", "main")); for (OnePath op : tsketch.vpaths) los.WriteLine(TNXML.xcom(2, "path", "class", "c1", "d", op.svgdvalue(0.0F, 0.0F))); los.WriteLine(TNXML.xcomclose(1, "g")); los.WriteLine(TNXML.xcomclose(0, "defs")); los.WriteLine(TNXML.xcom(1, "use", "xlink:href", "#main", "transform", "translate(500, 500)")); los.WriteLine(TNXML.xcomclose(0, "svg")); } } tunnelx-20140102.orig/src/SketchGraphics.java0000644000000000000000000032423212261213471015630 0ustar ///////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import javax.swing.JPanel; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.Line2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.geom.Ellipse2D; import java.awt.geom.AffineTransform; import java.awt.geom.GeneralPath; import java.awt.geom.NoninvertibleTransformException; import java.awt.Rectangle; import java.awt.Cursor; import java.awt.Dimension; import java.awt.Image; import java.util.List; import java.util.ArrayList; import java.util.Set; import java.util.HashSet; import java.util.SortedSet; import java.util.TreeSet; import java.util.Iterator; import java.util.Collections; import java.util.Map; import java.util.HashMap; import java.util.Collection; import java.util.Random; import java.util.Date; import java.awt.Color; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.event.MouseWheelListener; import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.geom.AffineTransform; import javax.swing.JCheckBoxMenuItem; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JProgressBar; import java.io.FileOutputStream; import java.io.IOException; // // // SketchGraphics // // //////////////////////////////////////////////////////////////////////////////// class SketchGraphics extends JPanel implements MouseListener, MouseMotionListener, MouseWheelListener { SketchDisplay sketchdisplay; static int SELECTWINDOWPIX = 5; static int MOVERELEASEPIX = 20; // the sketch. OneSketch skblank = new OneSketch(null); OneSketch tsketch = skblank; // cached paths of those on screen (used for speeding up of drawing during editing). Set tsvpathsvizbound = new HashSet(); // subset which has one area outside of selection Set tsvpathsviz = new HashSet(); SortedSet tsvareasviz = new TreeSet(); Set tsvnodesviz = new HashSet(); List tsvpathsframesimages = new ArrayList(); List tsvpathsframessubsets = new ArrayList(); List tspathssurvexlabel = new ArrayList(); List tsvpathsframesall = new ArrayList(); // merging of the above three lists boolean bEditable = false; OnePath currgenpath = null; OneSArea currselarea = null; // the currently active mouse path information. Line2D.Float moulin = new Line2D.Float(); GeneralPath moupath = new GeneralPath(); Ellipse2D elevpoint = new Ellipse2D.Float(); GeneralPath elevarrow = new GeneralPath(); int nmoupathpieces = 1; int nmaxmoupathpieces = 30; int[] moupiecesfblo = new int[nmaxmoupathpieces]; int[] moupiecesfbhi = new int[nmaxmoupathpieces]; boolean bmoulinactive = false; boolean bSketchMode = false; float moulinmleng = 0; Point2D.Float scrpt = new Point2D.Float(); Point2D.Float moupt = new Point2D.Float(); Rectangle selrect = new Rectangle(); Rectangle windowrect = new Rectangle(); OnePathNode selpathnode = null; OnePathNode currpathnode = null; OnePathNode selpathnodecycle = null; // used for cycling the selection // the array of array of paths which are going to define a boundary List vactivepaths = new ArrayList(); List vactivepathsnodecounts = new ArrayList(); // sort this. size = 2 * vactivepaths.size() // makes subselections from vactive paths for the components (set up by SelectConnectedSetsFromSelection) int[] vactivepathcomponentpairs = new int[40]; // this is a sequence of pairs that subselects vactivepaths int nvactivepathcomponents = -1; int ivactivepathcomponents = -1; int ivactivepathcomponents_wholeselection = -1; int icurrgenvactivepath = -1; // indexes currgenpath when it was incoming (useful for the FuseTranslate) Dimension csize = new Dimension(0, 0); SketchGrid sketchgrid = null; int xoc = 0; int yoc = 0; float ox = 0; float oy = 0; // values used by the dynamic rotate and scale int prevx = 0; int prevy = 0; // mouse motion state final static int M_NONE = 0; final static int M_DYN_ROT = 1; final static int M_DYN_DRAG = 2; final static int M_DYN_SCALE = 3; final static int M_SEL_STATIONS = 4; final static int M_SEL_XSECTIONS = 5; final static int M_SEL_TUBES = 6; final static int M_SEL_TUBE_CONE = 7; final static int M_SKET = 10; final static int M_SKET_SNAP = 11; final static int M_SKET_SNAPPED = 12; final static int M_SKET_END = 13; final static int M_SEL_PATH = 20; final static int M_SEL_PATH_ADD = 21; final static int M_SEL_PATH_NODE = 22; final static int M_SEL_AREA = 23; int momotion = M_NONE; // the bitmapped background ImageWarp backgroundimg = new ImageWarp(csize, this); Image mainImg = null; Graphics2D mainGraphics = null; int ibackimageredo = 0; // 0 redo everything, 1 except bitmap background, // 2 except partial sketch caching, 3 except redrawing the background sketch (just the overlay), int bkifrm = 0; boolean bNextRenderDetailed = false; boolean bNextRenderPinkDownSketch = false; boolean bNextRenderAreaStripes = false; AffineTransform orgtrans = new AffineTransform(); AffineTransform mdtrans = new AffineTransform(); double mdtransrotate = 0.0F; AffineTransform currtrans = new AffineTransform(); double currtransrotate = 0.0F; // poss not used to show the rotation. try to take it out if poss ///////////////////////////////////////////// SketchGraphics(SketchDisplay lsketchdisplay) { super(false); // not doublebuffered skblank.SetupSK(); setBackground(TN.wfmBackground); setForeground(TN.wfmLeg); addMouseListener(this); addMouseMotionListener(this); addMouseWheelListener(this); sketchdisplay = lsketchdisplay; backgroundimg.sketchgraphicspanel = this; //Some cursor sets have thick crosses which mean that a cross cursor type is rubbish for drawing //A thin cross cursor as I believe was originally intended would be reasonable. Martin //setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR)); } ///////////////////////////////////////////// void RedoBackgroundView() { ibackimageredo = 0; backgroundimg.bBackImageDoneGood = false; repaint(); } // this keeps all caching void RedrawBackgroundView() { ibackimageredo = 2; repaint(); } ///////////////////////////////////////////// boolean ElevBackImageWarp() { if (currgenpath.nlines != 1) return TN.emitWarning("not a line segment"); float[] pco = currgenpath.GetCoords(); float vx = pco[2] - pco[0]; float vy = pco[3] - pco[1]; mdtrans.setToTranslation(pco[0], pco[1]); mdtrans.shear(0.0, vy/vx); mdtrans.translate(-pco[0], -pco[1]); currtrans.concatenate(mdtrans); backgroundimg.PreConcatBusiness(mdtrans); DeleteSel(); //currtrans.concatenate(mdtrans); RedoBackgroundView(); return true; } ///////////////////////////////////////////// // 2 Maximize View // 1 Centre View // 12 Maximize Subset View // 121 Maximize Select View // 11 Centre Subset View // 122 Centre Select View void MaxAction(int imaxaction) { if (imaxaction != 3) { // imaxaction == 1, 2, 11, 12, 121, 122 Rectangle2D boundrect; if ((imaxaction == 121) || (imaxaction == 122)) boundrect = GetSelectedRange(); else boundrect = tsketch.getBounds(true, (imaxaction >= 11)); if ((boundrect.getWidth() != 0.0F) && (boundrect.getHeight() != 0.0F)) { // set the pre transformation mdtrans.setToTranslation(getSize().width / 2, getSize().height / 2); // scale change if ((imaxaction == 2) || (imaxaction == 12) || (imaxaction == 121)) { if ((getSize().width != 0) && (getSize().height != 0)) { double scchange = Math.max(boundrect.getWidth() / (getSize().width * 0.9F), boundrect.getHeight() / (getSize().height * 0.9F)); if (scchange != 0.0F) mdtrans.scale(1.0F / scchange, 1.0F / scchange); } } else { double scaX = Math.sqrt(currtrans.getScaleX()*currtrans.getScaleX() + currtrans.getShearX()*currtrans.getShearX()); mdtrans.scale(scaX, scaX); } mdtrans.translate(-(boundrect.getX() + boundrect.getWidth() / 2), -(boundrect.getY() + boundrect.getHeight() / 2)); } //else // mdtrans.setToIdentity(); orgtrans.setTransform(currtrans); currtrans.setTransform(mdtrans); } else // Set Upright (undoing the rotate and tilt) { double scaX = Math.sqrt(currtrans.getScaleX()*currtrans.getScaleX() + currtrans.getShearX()*currtrans.getShearX()); double scaY = Math.sqrt(currtrans.getScaleY()*currtrans.getScaleY() + currtrans.getShearY()*currtrans.getShearY()); TN.emitMessage("Ortho mat " + scaX + " " + scaY); currtrans.setTransform(scaX, 0, 0, scaX, currtrans.getTranslateX(), currtrans.getTranslateY()); UpdateTilt(false); assert scaTilt == 1.0; } RedoBackgroundView(); } ///////////////////////////////////////////// void UpdateBottTabbedPane(OnePath op, OneSArea osa, boolean btabbingchanged) { if (sketchdisplay.bottabbedpane.getSelectedIndex() == 0) sketchdisplay.subsetpanel.UpdateSubsetsOfPath(op); else if (sketchdisplay.bottabbedpane.getSelectedIndex() == 1) sketchdisplay.backgroundpanel.UpdateBackimageCombobox(1); else if (sketchdisplay.bottabbedpane.getSelectedIndex() == 2) { if (op != null) sketchdisplay.infopanel.SetPathXML(op, tsketch.sketchLocOffset); else if (osa != null) sketchdisplay.infopanel.SetAreaInfo(osa, tsketch); else if (btabbingchanged) sketchdisplay.infopanel.SetSketchInfo(tsketch); else sketchdisplay.infopanel.SetCleared(); } else if (sketchdisplay.bottabbedpane.getSelectedIndex() == 3) // use windowrect when no subsets selected { if (btabbingchanged) { sketchdisplay.printingpanel.subsetrect = tsketch.getBounds(true, true); RedrawBackgroundView(); } sketchdisplay.printingpanel.UpdatePrintingRectangle(tsketch.sketchLocOffset, tsketch.realposterpaperscale, btabbingchanged); } else if (sketchdisplay.bottabbedpane.getSelectedIndex() == 4) { sketchdisplay.secondrender.Update(btabbingchanged); } } // separate out the observed selection for this so we update the rectangle when there is a change of seleciton // find out how to make the background alpha channel binary // check the splitter window on left works // draw the centreline heavy // emboss and fill in around the words ///////////////////////////////////////////// void ObserveSelection(OnePath op, OneSArea osa, int yi) { assert (op == null) || (osa == null); sketchdisplay.sketchlinestyle.SetParametersIntoBoxes(op); //System.out.println("oooooo ooo " + yi); UpdateBottTabbedPane(op, osa, false); sketchdisplay.acaAddImage.setEnabled(op == null); boolean btwothreepointpath = (op != null) && ((op.nlines == 1) || (op.nlines == 2)); sketchdisplay.acaMoveBackground.setEnabled(btwothreepointpath && (tsketch.opframebackgrounddrag != null)); sketchdisplay.acaMovePicture.setEnabled(btwothreepointpath); sketchdisplay.acaReloadImage.setEnabled((op != null) && op.IsSketchFrameConnective()); sketchdisplay.acvSetGridOrig.setEnabled(op != null); sketchdisplay.acaReflect.setEnabled((op != null) && (op.linestyle != SketchLineStyle.SLS_CENTRELINE)); sketchdisplay.acaImportCentrelineFile.setEnabled(op == null); boolean bsurvexlabel = (((op != null) && op.IsSurvexLabel()) || !tspathssurvexlabel.isEmpty()); sketchdisplay.acaPreviewLabelWireframe.setEnabled(bsurvexlabel); sketchdisplay.acaImportLabelCentreline.setEnabled(bsurvexlabel); sketchdisplay.menuImportPaper.setEnabled((op == null) || ((op.linestyle == SketchLineStyle.SLS_CONNECTIVE) && (op.plabedl != null) && (op.plabedl.barea_pres_signal == SketchLineStyle.ASE_SKETCHFRAME) && op.vssubsets.isEmpty())); } OnePath pathaddlastsel = null; ///////////////////////////////////////////// // do all the selections of things void SelectAction() { // transform required for selection to work. mainGraphics.setTransform(currtrans); // do the selection of paths if (momotion == M_SEL_PATH) { OnePath selgenpath = tsketch.SelPath(mainGraphics, selrect, currgenpath, tsvpathsviz); ClearSelection(true); repaint(); if (selgenpath != null) { currgenpath = selgenpath; ObserveSelection(currgenpath, null, 2); } momotion = M_NONE; } // do the selection of areas if (momotion == M_SEL_AREA) { OneSArea lcurrselarea = tsketch.SelArea(mainGraphics, selrect, currselarea, tsvareasviz); ClearSelection(true); repaint(); currselarea = lcurrselarea; ObserveSelection(null, currselarea, 3); momotion = M_NONE; } // do the selection of paths to add if (momotion == M_SEL_PATH_ADD) { // push current selected path in the list. if (currgenpath != null) { AddVActivePath(currgenpath); currgenpath = null; } // find a path and invert toggle it in the list. OnePath selgenpath = tsketch.SelPath(mainGraphics, selrect, pathaddlastsel, tsvpathsviz); // toggle in list. if (selgenpath != null) { pathaddlastsel = selgenpath; CollapseVActivePathComponent(); if (vactivepaths.contains(selgenpath)) { RemoveVActivePath(selgenpath); ObserveSelection(null, null, 4); } else { AddVActivePath(selgenpath); ObserveSelection(selgenpath, null, 5); } } else pathaddlastsel = null; momotion = M_NONE; } // do the selection of pathnodes if (momotion == M_SKET_SNAP) { OnePathNode opfront =(bmoulinactive && (currgenpath != null) ? currgenpath.pnstart : null); boolean bopfrontvalid = ((opfront != null) && (currgenpath.nlines >= 2)); selpathnode = tsketch.SelNode(opfront, bopfrontvalid, mainGraphics, selrect, selpathnodecycle, tsvnodesviz); if (selpathnode == null) momotion = M_NONE; else { selpathnodecycle = selpathnode; if (!bmoulinactive) SetMouseLine(selpathnode.pn, selpathnode.pn); } } // the drop through into snapped mode if ((momotion == M_SKET_SNAPPED) || (momotion == M_SKET_SNAP)) { if (momotion == M_SKET_SNAPPED) { if (mainGraphics.hit(selrect, selpathnode.Getpnell(), false)) currpathnode = selpathnode; else currpathnode = null; } else { momotion = M_SKET_SNAPPED; currpathnode = selpathnode; } // snap the mouse line to it. if (bmoulinactive && (currpathnode != null)) { if (currgenpath == null) SetMouseLine(currpathnode.pn, null); else SetMouseLine(null, currpathnode.pn); } } } ///////////////////////////////////////////// float GetMidZsel() { return (sketchdisplay.ztiltpanel.bzthinnedvisible ? (float)(sketchdisplay.ztiltpanel.zlothinnedvisible + sketchdisplay.ztiltpanel.zhithinnedvisible) / 2 : 0.0F); } ///////////////////////////////////////////// float zloselected = 0.0F; float zhiselected = 0.0F; boolean bzrselected = false; Rectangle2D GetSelectedRange() { zloselected = 0.0F; zhiselected = 0.0F; bzrselected = false; Rectangle2D.Float selbounds = new Rectangle2D.Float(); if ((currgenpath != null) && (currgenpath.pnend != null)) { zloselected = Math.min(currgenpath.pnstart.zalt, currgenpath.pnend.zalt); zhiselected = Math.max(currgenpath.pnstart.zalt, currgenpath.pnend.zalt); bzrselected = true; selbounds.setRect(currgenpath.getBounds(null)); } if (currselarea != null) { for (RefPathO rpo : currselarea.refpaths) { float zalt = rpo.ToNode().zalt; if (!bzrselected || (zalt < zloselected)) zloselected = zalt; if (!bzrselected || (zalt > zhiselected)) zhiselected = zalt; if (bzrselected) selbounds.add(rpo.op.getBounds(null)); else selbounds.setRect(rpo.op.getBounds(null)); bzrselected = true; } } for (OnePath op : vactivepaths) { float zlo = Math.min(op.pnstart.zalt, op.pnend.zalt); float zhi = Math.max(op.pnstart.zalt, op.pnend.zalt); if (!bzrselected || (zlo < zloselected)) zloselected = zlo; if (!bzrselected || (zhi > zhiselected)) zhiselected = zhi; if (bzrselected) selbounds.add(op.getBounds(null)); else selbounds.setRect(op.getBounds(null)); bzrselected = true; } return selbounds; } ///////////////////////////////////////////// // todo // // get the overlay drawn properly // move the thinzlevels selection into the background/gridlines tab // overlay could also draw up where the mouse is on the edge // allow for middle mouse button click to extend/shorten this range // make sure new edges are added to mid-point of selection or the midpoint of visible // implement the *title " "; " "; " " // implement the *uppertitle " "... ///////////////////////////////////////////// void RenderBackground() { mainGraphics.setTransform(id); // this is due to the background moving if ((ibackimageredo == 0) && sketchdisplay.miShowGrid.isSelected() && (sketchgrid != null)) sketchgrid.UpdateGridCoords(csize, currtrans, sketchdisplay.miEnableRotate.isSelected(), sketchdisplay.backgroundpanel); if ((ibackimageredo == 0) && (sketchdisplay.bottabbedpane.getSelectedIndex() == 3)) // use windowrect when no subsets selected sketchdisplay.printingpanel.UpdatePrintingRectangle(tsketch.sketchLocOffset, tsketch.realposterpaperscale, true); // render the background // this is working independently of ibackimageredo for now boolean bNewBackgroundExists = ((tsketch.opframebackgrounddrag != null) && (tsketch.opframebackgrounddrag.plabedl != null) && (tsketch.opframebackgrounddrag.plabedl.sketchframedef != null)); boolean bClearBackground = (!bNewBackgroundExists || !sketchdisplay.miShowBackground.isSelected()); if (!bClearBackground && !backgroundimg.bBackImageGood) { backgroundimg.bBackImageGood = true; bClearBackground = !backgroundimg.bBackImageGood; } // we have a background. if (!bClearBackground && !backgroundimg.bBackImageDoneGood) { backgroundimg.SketchBackground(currtrans); backgroundimg.bBackImageDoneGood = true; } // now draw our cached background or fill it with empty. if (bClearBackground) { mainGraphics.setColor(Color.white); mainGraphics.fillRect(0, 0, csize.width, csize.height); } else mainGraphics.drawImage(backgroundimg.backimagedone, 0, 0, null); // as if the above was using this flag correctly if (ibackimageredo == 0) ibackimageredo = 1; // render the image on top of the background. TN.emitMessage("backimgdraw " + bkifrm++ + " " + ibackimageredo + " " + bClearBackground); // drawing stuff on top mainGraphics.setTransform(currtrans); //double tsca = Math.min(currtrans.getScaleX(), currtrans.getScaleY()); double scaX = Math.sqrt(currtrans.getScaleX()*currtrans.getScaleX() + currtrans.getShearX()*currtrans.getShearX()); // caching the paths which are in view if (ibackimageredo == 1) { tsvpathsviz.clear(); tsvpathsvizbound.clear(); tsvareasviz.clear(); tsvnodesviz.clear(); tsvpathsframesimages.clear(); tsvpathsframessubsets.clear(); tspathssurvexlabel.clear(); // accelerate this caching if we are zoomed out a lot (using the max calculation) Rectangle2D boundrect = tsketch.getBounds(false, false); double scchange = Math.max(boundrect.getWidth() / (getSize().width * 0.9F), boundrect.getHeight() / (getSize().height * 0.9F)); if ((scchange * scaX > 1.9) || sketchdisplay.ztiltpanel.bzthinnedvisible) { // do the zslicing of the paths and areas here Collection lvpathsviz; Collection lvsareasviz; if (sketchdisplay.ztiltpanel.bzthinnedvisible) { lvpathsviz = new HashSet(); lvsareasviz = new HashSet(); for (OnePath op : tsketch.vpaths) { op.MakeZsliced(sketchdisplay.ztiltpanel.zlothinnedvisible, sketchdisplay.ztiltpanel.zhithinnedvisible); if (op.gpzsliced != null) { lvpathsviz.add(op); if (op.kaleft != null) lvsareasviz.add(op.kaleft); if (op.karight != null) lvsareasviz.add(op.karight); } } for (OneSArea osa : lvsareasviz) { // get paths in each area, have the ones on the boundary greyed by putting into tsvpathsvizbound instead for (RefPathO rpo : osa.refpaths) { OneSArea osacross = rpo.GetCrossArea(); if ((osacross == null) || lvsareasviz.contains(osacross)) lvpathsviz.add(rpo.op); else if (mainGraphics.hit(windowrect, rpo.op.gp, (rpo.op.linestyle != SketchLineStyle.SLS_FILLED))) tsvpathsvizbound.add(rpo.op); } for (ConnectiveComponentAreas cca : osa.ccalist) { lvpathsviz.addAll(cca.vconnpaths); lvpathsviz.addAll(cca.vconnpathsrem); } } } else { // use the originals before hit thinning lvpathsviz = tsketch.vpaths; lvsareasviz = tsketch.vsareas; } // now thin by visibility for (OnePath op : lvpathsviz) { boolean bcountasfilled = ((op.linestyle == SketchLineStyle.SLS_FILLED) || op.IsSketchFrameConnective()); if ((mainGraphics.hit(windowrect, op.gp, !bcountasfilled) || ((op.plabedl != null) && (op.plabedl.drawlab != null) && (op.plabedl.rectdef != null) && mainGraphics.hit(selrect, op.plabedl.rectdef, false)))) { tsvpathsviz.add(op); if (op.IsSketchFrameConnective() && !op.plabedl.sketchframedef.sfsketch.equals("")) tsvpathsframesimages.add(op); // do the visibility of the nodes around it (it's a set so doesn't mind duplicates) if (!sketchdisplay.ztiltpanel.bzthinnedvisible || ((sketchdisplay.ztiltpanel.zlothinnedvisible <= op.pnstart.zalt) && (op.pnstart.zalt <= sketchdisplay.ztiltpanel.zhithinnedvisible))) tsvnodesviz.add(op.pnstart); if (!sketchdisplay.ztiltpanel.bzthinnedvisible || ((sketchdisplay.ztiltpanel.zlothinnedvisible <= op.pnend.zalt) && (op.pnend.zalt <= sketchdisplay.ztiltpanel.zhithinnedvisible))) tsvnodesviz.add(op.pnend); } // survex label scans across all places if (op.IsSurvexLabel()) tspathssurvexlabel.add(op); if (op.IsSketchFrameConnective() && op.plabedl.sketchframedef.sfsketch.equals("") && !op.plabedl.sketchframedef.submapping.isEmpty()) tsvpathsframessubsets.add(op); } for (OneSArea osa : lvsareasviz) { if (mainGraphics.hit(windowrect, osa.gparea, false)) tsvareasviz.add(osa); } } else { tsvpathsviz.addAll(tsketch.vpaths); tsvareasviz.addAll(tsketch.vsareas); tsvnodesviz.addAll(tsketch.vnodes); for (OnePath op : tsvpathsviz) { if (op.IsSketchFrameConnective() && !op.plabedl.sketchframedef.sfsketch.equals("")) tsvpathsframesimages.add(op); if (op.IsSurvexLabel()) tspathssurvexlabel.add(op); if (op.IsSketchFrameConnective() && op.plabedl.sketchframedef.sfsketch.equals("") && !op.plabedl.sketchframedef.submapping.isEmpty()) tsvpathsframessubsets.add(op); } } tsvpathsframesall.clear(); tsvpathsframesall.addAll(tspathssurvexlabel); tsvpathsframesall.addAll(tsvpathsframessubsets); tsvpathsframesall.addAll(tsvpathsframesimages); // account for unreliable setting sketchdisplay.acaPreviewLabelWireframe.setEnabled(!tspathssurvexlabel.isEmpty()); sketchdisplay.acaImportLabelCentreline.setEnabled(!tspathssurvexlabel.isEmpty()); ibackimageredo = 2; if (sketchdisplay.bottabbedpane.getSelectedIndex() == 1) sketchdisplay.backgroundpanel.UpdateBackimageCombobox(0); } // the grid thing if (sketchdisplay.miShowGrid.isSelected() && (sketchgrid != null)) { mainGraphics.setStroke(SketchLineStyle.gridStroke); // thin mainGraphics.setColor(SketchLineStyle.gridColor); // black mainGraphics.draw(sketchgrid.gpgrid); } // draw the sketch according to what view we want (incl single frame of print quality) boolean bHideMarkers = !sketchdisplay.miShowNodes.isSelected(); int stationnamecond = (sketchdisplay.miStationNames.isSelected() ? 1 : 0) + (sketchdisplay.miStationAlts.isSelected() ? 2 : 0); boolean bHideSymbols = (scaX < 0.2); if (bHideSymbols) TN.emitMessage("hiding symbols because scale is " + scaX); GraphicsAbstraction ga = new GraphicsAbstraction(mainGraphics); if (bNextRenderDetailed) { if (SketchLineStyle.bDepthColours) { ga.depthcolourswindowrect = windowrect; ga.depthcolourswidthstep = 10.0 / scaX; // an area every 10 pixels on the screen } tsketch.paintWqualitySketch(ga, sketchdisplay.printingpanel.cbRenderingQuality.getSelectedIndex(), sketchdisplay.sketchlinestyle.subsetattrstylesmap); } else tsketch.paintWbkgd(ga, !sketchdisplay.miCentreline.isSelected(), bHideMarkers, stationnamecond, bHideSymbols, tsvpathsviz, tsvpathsvizbound, tsvareasviz, tsvnodesviz, sketchdisplay.ztiltpanel.bzthinnedvisible); // all back image stuff done. Now just the overlays. ibackimageredo = 3; } AffineTransform id = new AffineTransform(); // identity ///////////////////////////////////////////// public void paintComponent(Graphics g) { boolean bDynBackDraw = ((momotion == M_DYN_DRAG) || (momotion == M_DYN_SCALE) || (momotion == M_DYN_ROT)); if (bNextRenderDetailed) ibackimageredo = 2; // test if resize has happened because we are rebuffering things // then go in again. if ((mainImg == null) || (getSize().height != csize.height) || (getSize().width != csize.width)) { csize.width = getSize().width; csize.height = getSize().height; windowrect.setRect(0, 0, csize.width, csize.height); mainImg = createImage(csize.width, csize.height); mainGraphics = (Graphics2D)mainImg.getGraphics(); RedoBackgroundView(); return; } // do all the selection stuff, all based on momotion SelectAction(); // now we start rendering what is into the mainGraphics. // when rendering is complete, we draw it in the front. // paint the background in. Graphics2D g2D = (Graphics2D)g; // this contains a reference to g2D and doesn't quite encapsulate all the functions yet. should it? Was for production of SVG and other such outputs AffineTransform orgtrans = g2D.getTransform(); GraphicsAbstraction ga = new GraphicsAbstraction(g2D); if (!bDynBackDraw) { // the rendering of the background image is already included in the background. if (ibackimageredo <= 2) RenderBackground(); assert(ibackimageredo == 3); g2D.drawImage(mainImg, 0, 0, null); } // drawing of bitmap for quick dynamic dragging else { // simply redraw the back image into the front, transformed for fast dynamic rendering. g2D.setColor(TN.skeBackground); g2D.fillRect(0, 0, csize.width, csize.height); g2D.drawImage(mainImg, mdtrans, null); } // // draw the active paths over it in the real window buffer. // ga.transform(currtrans); ga.SetMainClip(); g2D.setFont(sketchdisplay.sketchlinestyle.defaultfontlab); // draw the tilted view if (sketchdisplay.miShowTilt.isSelected()) { AffineTransform satrans = g2D.getTransform(); if (!bDynBackDraw) UpdateTilt(false); // need to premultiply the scale transform // Very difficult to avoid the stroke drawn with the proper width and not be scaled // Need to draw this entirely without a transform g2D.setTransform(orgtrans); //ga.g2d.scale(1.0, 1.0/scaTilt); //ga.transform(currtrans); boolean bHideCentreline = !sketchdisplay.miCentreline.isSelected(); // Does the selection component subset system get drawn by same function too? //List jvpaths = (nvactivepathcomponents == -1 ? tsketch.vpaths : vactivepaths); //int a = (ivactivepathcomponents == -1 ? 0 : vactivepathcomponentpairs[ivactivepathcomponents*2]); //int b = (ivactivepathcomponents == -1 ? tsketch.vpaths.size() : vactivepathcomponentpairs[ivactivepathcomponents*2+1]); for (OnePath op : tsketch.vpaths) { //OnePath op = jvpaths.get(i); if ((op.linestyle == SketchLineStyle.SLS_INVISIBLE) || (op.linestyle == SketchLineStyle.SLS_CONNECTIVE) || (bHideCentreline && (op.linestyle == SketchLineStyle.SLS_CENTRELINE))) continue; boolean bIsSubsetted = (!tsketch.bRestrictSubsetCode || op.bpathvisiblesubset); if (!bIsSubsetted) continue; if (op.gptiltin != null) { LineStyleAttr linestyleattr = SketchLineStyle.ActiveLineStyleAttrs[op.linestyle]; g2D.setColor(linestyleattr.strokecolour); g2D.setStroke(linestyleattr.linestroke); g2D.draw(op.gptiltin); } if (op.gptiltout != null) { LineStyleAttr linestyleattr = SketchLineStyle.notInSelSubsetLineStyleAttrs[op.linestyle]; g2D.setColor(linestyleattr.strokecolour); g2D.setStroke(linestyleattr.linestroke); g2D.draw(op.gptiltout); } } g2D.setTransform(satrans); } //if (tsketch.opframebackgrounddrag != null) // ga.drawPath(tsketch.opframebackgrounddrag, SketchLineStyle.framebackgrounddragstyleattr); // draw all the active paths, or just a selected component if (nvactivepathcomponents == -1) { for (OnePath op : vactivepaths) op.paintW(ga, false, true); } else { int a = vactivepathcomponentpairs[ivactivepathcomponents*2]; int b = vactivepathcomponentpairs[ivactivepathcomponents*2+1]; System.out.println("a="+a+" b="+b+" vactivepaths,size()="+vactivepaths.size()); for (int i = a; i < b; i++) vactivepaths.get(i).paintW(ga, false, true); } int ipn = 0; while (ipn < vactivepathsnodecounts.size()) { int pipn = ipn++; while ((ipn < vactivepathsnodecounts.size()) && (vactivepathsnodecounts.get(ipn) == vactivepathsnodecounts.get(pipn))) ipn++; if (((ipn - pipn) % 2) == 1) ga.drawShape(vactivepathsnodecounts.get(pipn).Getpnell(), SketchLineStyle.activepnlinestyleattr); } // the current node if ((momotion == M_SKET_SNAPPED) && (currpathnode != null)) { ga.drawShape(currpathnode.Getpnell(), SketchLineStyle.activepnlinestyleattr); if ((currpathnode.IsCentrelineNode()) && sketchdisplay.miStationNames.isSelected()) ga.drawString(currpathnode.pnstationlabel, SketchLineStyle.stationPropertyFontAttr, (float)currpathnode.pn.getX() + SketchLineStyle.strokew * 2, (float)currpathnode.pn.getY() - SketchLineStyle.strokew); if (!bmoulinactive) ga.drawShape(moupath, SketchLineStyle.activepnlinestyleattr); // moulin } // draw the selected/active paths. if (currgenpath != null) { // do we have a Frame sketch if ((currgenpath.plabedl != null) && (currgenpath.plabedl.barea_pres_signal == SketchLineStyle.ASE_SKETCHFRAME) && ((currgenpath.karight != null) || (currgenpath.kaleft != null)) && ((currgenpath.plabedl.sketchframedef.pframesketch != null) || (currgenpath.plabedl.sketchframedef.pframeimage != null))) { AffineTransform satrans = g2D.getTransform(); ga.transform(currgenpath.plabedl.sketchframedef.pframesketchtrans); if (currgenpath.plabedl.sketchframedef.pframeimage != null) ga.drawImage(currgenpath.plabedl.sketchframedef.pframeimage.GetImage(true)); if (currgenpath.plabedl.sketchframedef.pframesketch != null) { // normal plan projection of sketch if (currgenpath.plabedl.sketchframedef.sfelevrotdeg == 0.0) { OneSketch asketch = currgenpath.plabedl.sketchframedef.pframesketch; //System.out.println("Plotting frame sketch " + asketch.vpaths.size() + " " + satrans.toString()); for (OnePath op : asketch.vpaths) { if ((op.linestyle != SketchLineStyle.SLS_CENTRELINE) && (op.linestyle != SketchLineStyle.SLS_CONNECTIVE)) op.paintW(ga, true, true); } } // elevation projection of sketch else { currgenpath.plabedl.sketchframedef.MakeElevClines(false); for (ElevCLine ecl : currgenpath.plabedl.sketchframedef.elevclines) ga.drawShape(ecl.gp, SketchLineStyle.ActiveLineStyleAttrs[ecl.linestyle]); } } g2D.setTransform(satrans); } // draw the symbols on this path for (OneSSymbol oss : currgenpath.vpsymbols) oss.paintW(ga, true, false); // draw the endpoints different colours so we can determin handedness. if (currgenpath.pnstart != null) ga.drawShape(currgenpath.pnstart.Getpnell(), SketchLineStyle.firstselpnlinestyleattr); if (currgenpath.pnend != null) ga.drawShape(currgenpath.pnend.Getpnell(), SketchLineStyle.lastselpnlinestyleattr); currgenpath.paintW(ga, false, true); } // draw in the selected area outline (what will be put into the subset). if (currselarea != null) { for (RefPathO rpo : currselarea.refpaths) rpo.op.paintW(ga, false, true); for (ConnectiveComponentAreas cca : currselarea.ccalist) { for (OnePath sop : cca.vconnpaths) sop.paintW(ga, false, true); for (OnePath sop : cca.vconnpathsrem) sop.paintW(ga, false, true); } for (int i = 0; i < currselarea.nconnpathremaining; i++) currselarea.connpathrootscen.get(i).paintW(ga, false, true); } // draw the rubber band. if (bmoulinactive) ga.drawShape(moupath, SketchLineStyle.ActiveLineStyleAttrs[SketchLineStyle.SLS_DETAIL]); // moulin/ // deal with the overlays bNextRenderDetailed = false; // draw the areas in hatched if (bNextRenderAreaStripes) { if ((currgenpath != null) && (currgenpath.pthcca != null)) { int i = 0; for (OneSArea osa : currgenpath.pthcca.vconnareas) osa.paintHatchW(ga, i++); } else { int i = 0; for (OneSArea osa : tsketch.vsareas) osa.paintHatchW(ga, i++); } bNextRenderAreaStripes = false; } // paint the down sketches that we are going to import (this is a preview). // this messes up the ga.transform. if (bNextRenderPinkDownSketch) { OneSketch lselectedsketch = sketchdisplay.mainbox.tunnelfilelist.GetSelectedSketchLoad(); if (lselectedsketch != null) paintSelectedSketch(ga, lselectedsketch); else TN.emitWarning("No sketch selected"); bNextRenderPinkDownSketch = false; } // this is where that elevation blob is drawn if (sketchdisplay.selectedsubsetstruct.elevset.bIsElevStruct) //ga.drawShape(elevpoint, SketchLineStyle.ActiveLineStyleAttrs[SketchLineStyle.SLS_DETAIL]); ga.drawShape(elevarrow, SketchLineStyle.ActiveLineStyleAttrs[SketchLineStyle.SLS_DETAIL]); // new todenode overlay if (TN.bTodeNode) sketchdisplay.todenodepanel.painttodenode(ga); // for the purpose of animations if (sketchdisplay.ztiltpanel.cbaAnimateTour.isSelected()) sketchdisplay.ztiltpanel.buttanimatestep.doClick(0); } ///////////////////////////////////////////// // dimensions of the paper are given in metres (then multiplied up by 1000 so that the font stuff actually works) // An entirely new set of fonts and linewidths will be required on this paper level (all the title stuff I guess) boolean ImportPaperM(String papersize, float lwidth, float lheight) { // set the poster scale to 1000 if there are no imported sketches here already if (tsketch.realposterpaperscale == 1.0) { int nimportedsketches = 0; for (OnePath op : tsketch.vpaths) { if (op.IsSketchFrameConnective() && !op.plabedl.sketchframedef.IsImageType()) nimportedsketches++; } if (nimportedsketches == 0) tsketch.realposterpaperscale = TN.defaultrealposterpaperscale; else return TN.emitWarning("Cannot import paper (and reset realposterpaperscale) because there are "+nimportedsketches+" imported sketches"); } float pwidth = (float)(lwidth * tsketch.realposterpaperscale * TN.CENTRELINE_MAGNIFICATION); float pheight = (float)(lheight * tsketch.realposterpaperscale * TN.CENTRELINE_MAGNIFICATION); List pthstoremove = new ArrayList(); List pthstoadd = new ArrayList(); OnePath opC; if (currgenpath != null) { if ((currgenpath.linestyle != SketchLineStyle.SLS_CONNECTIVE) || (currgenpath.plabedl == null) || (currgenpath.plabedl.barea_pres_signal != SketchLineStyle.ASE_SKETCHFRAME) || !currgenpath.vssubsets.isEmpty()) TN.emitError("Connective path, with frame area signal, not in any subset, must selected"); opC = currgenpath; } else { opC = MakeConnectiveLineForData(2, pwidth); pthstoadd.add(opC); } String sspapersubset = sketchdisplay.subsetpanel.GetNewPaperSubset(papersize); sketchdisplay.subsetpanel.PutToSubset(opC, TN.framestylesubset, true); sketchdisplay.subsetpanel.PutToSubset(opC, sspapersubset, true); OnePathNode opn00 = opC.pnstart; float x = (float)opn00.pn.getX(); float y = (float)opn00.pn.getY(); OnePathNode opn01 = new OnePathNode(x + pwidth, y, GetMidZsel()); OnePathNode opn10 = new OnePathNode(x, y + pheight, GetMidZsel()); OnePathNode opn11 = new OnePathNode(x + pwidth, y + pheight, GetMidZsel()); OnePath op0X = new OnePath(opn00); op0X.EndPath(opn01); op0X.linestyle = SketchLineStyle.SLS_INVISIBLE; sketchdisplay.subsetpanel.PutToSubset(op0X, sspapersubset, true); OnePath opX1 = new OnePath(opn01); opX1.EndPath(opn11); opX1.linestyle = SketchLineStyle.SLS_INVISIBLE; sketchdisplay.subsetpanel.PutToSubset(opX1, sspapersubset, true); OnePath op1X = new OnePath(opn11); op1X.EndPath(opn10); op1X.linestyle = SketchLineStyle.SLS_INVISIBLE; sketchdisplay.subsetpanel.PutToSubset(op1X, sspapersubset, true); OnePath opX0 = new OnePath(opn10); opX0.EndPath(opn00); opX0.linestyle = SketchLineStyle.SLS_INVISIBLE; sketchdisplay.subsetpanel.PutToSubset(opX0, sspapersubset, true); pthstoadd.add(opX0); pthstoadd.add(opX1); pthstoadd.add(op0X); pthstoadd.add(op1X); CommitPathChanges(pthstoremove, pthstoadd); vactivepaths.addAll(pthstoadd); if (currgenpath != null) vactivepaths.add(opC); MaxAction(121); return true; } ///////////////////////////////////////////// // take the sketch from the displayed window and import it from the selected sketch in the mainbox. void ImportSketch(OneSketch asketch, boolean bImportSubsetsOnCentreline, boolean bClearSubsetsOnCentreline, boolean bImportNoCentrelines) { if ((asketch == null) || (tsketch == asketch)) { TN.emitWarning(asketch == null ? "Sketch not selected" : "Can't import sketch onto itself"); return; } TN.emitMessage((bClearSubsetsOnCentreline ? "" : "Not ") + "Overwriting subsets info on centrelines"); PtrelLn ptrelln = new PtrelLn(); // all in one find the centreline paths and the corresponding paths we will export to. boolean bcorrespsucc = ptrelln.ExtractCentrelinePathCorrespondence(asketch, tsketch); ptrelln.realposterpaperscale = asketch.realposterpaperscale; //assert ptrelln.realposterpaperscale == tsketch.realposterpaperscale; // not a useful assert when we transition ptrelln.sketchLocOffsetFrom = asketch.sketchLocOffset; ptrelln.sketchLocOffsetTo = tsketch.sketchLocOffset; // do some connected components // clpaths is the list of paths in the imported sketch. corrpaths is the corresponding paths in the new sketch. TN.emitMessage("Finished finding centerline correspondence"); if (bcorrespsucc && (bImportSubsetsOnCentreline || bClearSubsetsOnCentreline)) { for (PtrelPLn wptreli : ptrelln.wptrel) { if (bClearSubsetsOnCentreline) wptreli.crp.vssubsets.clear(); if (bImportSubsetsOnCentreline) { for (String subset : wptreli.cp.vssubsets) // avoid duplicates if (!wptreli.crp.vssubsets.contains(subset)) wptreli.crp.vssubsets.add(subset); //wptreli.crp.vssubsets.addAll(wptreli.cp.vssubsets); } } TN.emitMessage("Finished copying centerline subsets"); } if (!bcorrespsucc) TN.emitMessage("no centreline correspondence here"); TN.emitMessage("Extending all nodes"); ptrelln.PrepareProximity(asketch); if (bcorrespsucc) ptrelln.CalcAvgTransform(ptrelln.ucavgtrans, null, null, null); else ptrelln.ucavgtrans.setToIdentity(); ptrelln.PrepareForUnconnectedNodes(asketch.vnodes); ptrelln.Extendallnodes(asketch.vnodes); TN.emitMessage("Warping all paths"); List cplist = new ArrayList(); for (PtrelPLn wptreli : ptrelln.wptrel) cplist.add(wptreli.cp); // warp over all the paths from the sketch int lastprogress = -1; int i = 0; String importfromname = asketch.sketchfile.getSketchName(); List pthstoremove = new ArrayList(); List pthstoadd = new ArrayList(); // this bit could be multithreaded for (OnePath op : asketch.vpaths) { if ((op.linestyle == SketchLineStyle.SLS_CENTRELINE) && (bImportNoCentrelines || cplist.contains(op))) continue; boolean bsurvexlabel = ((op.linestyle == SketchLineStyle.SLS_CONNECTIVE) && (op.plabedl != null) && op.plabedl.sfontcode.equals("survey")); if (bsurvexlabel) continue; pthstoadd.add(ptrelln.WarpPathD(op, importfromname)); int progress = (20*i) / asketch.vpaths.size(); i++; if (progress == lastprogress) continue; lastprogress = progress; TN.emitMessage("" + (5*progress) + "% complete at " + (new Date()).toString()); } CommitPathChanges(pthstoremove, pthstoadd); RedrawBackgroundView(); } ///////////////////////////////////////////// // take the sketch from the displayed window and import it into the selected sketch in the mainbox. AffineTransform avgtrans = new AffineTransform(); OneSketch asketchavglast = null; // used for lazy evaluation. void paintSelectedSketch(GraphicsAbstraction ga, OneSketch asketch) { // find new transform if it's a change. if (asketch != asketchavglast) { PtrelLn ptrelln = new PtrelLn(); boolean bcorrespsucc = ptrelln.ExtractCentrelinePathCorrespondence(asketch, tsketch); if (bcorrespsucc) ptrelln.CalcAvgTransform(avgtrans, null, null, null); else avgtrans.setToIdentity(); asketchavglast = asketch; } // now work from known transform ga.transform(avgtrans); // draw all the paths inactive. for (OnePath op : asketch.vpaths) { if (op.linestyle != SketchLineStyle.SLS_CENTRELINE) // of have it unhidden? op.paintW(ga, true, true); } } ///////////////////////////////////////////// boolean IsInBlack(double fx, double fy) { int rgb = backgroundimg.backimagedone.getRGB((int)(fx + 0.5F), (int)(fy + 0.5F)); // find intensity. int intens = ((rgb & 0xff) + (rgb & 0xff00) / 0x100 + (rgb & 0xff0000) / 0x10000); return (intens < (3 * 0x80)); } ///////////////////////////////////////////// Point2D.Float smpt0 = new Point2D.Float(); Point2D.Float smpt1 = new Point2D.Float(); Point2D.Float smidpt = new Point2D.Float(); Point2D.Float midptt = new Point2D.Float(); ///////////////////////////////////////////// float ptlx; float ptly; float perpx; float perpy; float tracklinesidefac = 2.5F; int nsampsides = 20; int nsampsidesmid = 30; boolean IsInBlack(int j) { return IsInBlack(ptlx + perpx * tracklinesidefac * j, ptly + perpy * tracklinesidefac * j); } int nmoupathpiecesleng = 15; ///////////////////////////////////////////// void SetMouseLine(Point2D pt0, Point2D pt1) { moulin.setLine((pt0 == null ? moulin.getX1() : pt0.getX()), (pt0 == null ? moulin.getY1() : pt0.getY()), (pt1 == null ? moulin.getX2() : pt1.getX()), (pt1 == null ? moulin.getY2() : pt1.getY())); // put the line into screen space. if (pt0 != null) currtrans.transform(pt0, smpt0); if (pt1 != null) currtrans.transform(pt1, smpt1); moulinmleng = (float)smpt0.distance(smpt1); nmoupathpieces = 1; if (sketchdisplay.miTrackLines.isSelected() && (backgroundimg.backimage != null) && ((currgenpath.linestyle != SketchLineStyle.SLS_CONNECTIVE))) { if (moulinmleng > nmoupathpiecesleng * 2) { // both endpoints should be in the black region. if (IsInBlack(smpt0.getX(), smpt0.getY()) && IsInBlack(smpt1.getX(), smpt1.getY())) { nmoupathpieces = Math.min(nmaxmoupathpieces, 1 + (int)(moulinmleng / nmoupathpiecesleng)); //TN.emitMessage("npieces:" + String.valueOf(nmoupathpieces)); // do some precalculations perpy = (float)(smpt1.getY() - smpt0.getY()) / moulinmleng; perpx = -(float)(smpt1.getX() - smpt0.getX()) / moulinmleng; } } } // work out how many pieces it will split into moupath.reset(); moupath.moveTo((float)moulin.getX1(), (float)moulin.getY1()); // loop through and find the scans on each side at all the points along the line float fbgapsum = 0.0F; // for working out the average width int fbgapn = 0; int fb0 = 0; // the end ones int fb1 = 0; for (int ia = 1; ia < nmoupathpieces; ia++) { int i = (((ia % 2) == 0) ? (ia / 2) : (nmoupathpieces - (ia + 1) / 2)); float lam = (float)i / nmoupathpieces; ptlx = (float)((1.0F - lam) * smpt0.getX() + lam * smpt1.getX()); ptly = (float)((1.0F - lam) * smpt0.getY() + lam * smpt1.getY()); // find the first black sample int fb = -1; int lnsampsides = (Math.abs(lam - 0.5F) < 0.3F ? nsampsidesmid : nsampsides); int fbmid = (fb0 + fb1) / 2; // scan outwards for the closest blackness to the centre for (int j = 0; j <= nsampsides; j++) { if (IsInBlack(j + fbmid)) { fb = j + fbmid; break; } if ((j != 0) && IsInBlack(-j + fbmid)) { fb = -j + fbmid; break; } } // skip this one, no black was found. moupiecesfblo[i] = -1; if (fb == -1) continue; // scan for highest and lowest black. int fblo = fb; if (fb <= 0) { while((fblo > -nsampsides) && IsInBlack(fblo - 1)) fblo--; } int fbhi = fb; if (fb >= 0) { while((fbhi < nsampsides) && IsInBlack(fbhi + 1)) fbhi++; } moupiecesfblo[i] = fblo; moupiecesfblo[i] = fbhi; fbgapsum += (fbhi - fblo); fbgapn++; if ((ia % 2) == 0) fb0 = fb; else fb1 = fb; } // width limit to avoid going up any perpendicular side segments float fbgapmax = (fbgapn != 0 ? fbgapsum / fbgapn : 0.0F) * 1.1F; // now rerun the array and discount sections that are too wide for (int i = 1; i < nmoupathpieces; i++) { if ((moupiecesfblo[i] == -1) || (moupiecesfbhi[i] - moupiecesfblo[i] > fbgapmax)) continue; float lam = (float)i / nmoupathpieces; ptlx = (float)((1.0F - lam) * smpt0.getX() + lam * smpt1.getX()); ptly = (float)((1.0F - lam) * smpt0.getY() + lam * smpt1.getY()); // now set the point to the mid sample block. float fbm = (moupiecesfblo[i] + moupiecesfbhi[i]) / 2.0F; //fbm = (i % nsampsides) * ((i % 2) == 0 ? 1 : -1); smidpt.setLocation(ptlx + perpx * tracklinesidefac * fbm, ptly + perpy * tracklinesidefac * fbm); try { currtrans.inverseTransform(smidpt, midptt); } catch (NoninvertibleTransformException ex) {;} moupath.lineTo((float)midptt.getX(), (float)midptt.getY()); } moupath.lineTo((float)moulin.getX2(), (float)moulin.getY2()); //if (backgroundimg.backimage != null) // TN.emitMessage(backgroundimg.backimage.getRGB(e.getX(), e.getY())); } ///////////////////////////////////////////// // mouse events ///////////////////////////////////////////// ///////////////////////////////////////////// void SetMPoint(MouseEvent e) { try { scrpt.setLocation(e.getX(), e.getY()); currtrans.inverseTransform(scrpt, moupt); } catch (NoninvertibleTransformException ex) { moupt.setLocation(0, 0); } if (sketchdisplay.miSnapToGrid.isSelected() && sketchdisplay.miShowGrid.isSelected()) sketchgrid.ClosestGridPoint(moupt, moupt.getX(), moupt.getY(), -1.0); } ///////////////////////////////////////////// public void mouseWheelMoved(MouseWheelEvent e) { if ((momotion == M_DYN_DRAG) || (momotion == M_DYN_SCALE) || (momotion == M_DYN_ROT)) return; double rescalew = Math.pow(0.66F, e.getWheelRotation()); // almost always +1 or -1 // protect zooming too far in relation to the width of the line. // it freezes if zoom out too far with thin lines. double plinewidth = currtrans.getScaleX() * rescalew * sketchdisplay.sketchlinestyle.strokew; if ((rescalew < 1.0) && (rescalew * plinewidth < 0.001)) return; if ((rescalew > 1.0) && (rescalew * plinewidth > 100.0)) return; orgtrans.setTransform(currtrans); mdtrans.setToIdentity(); prevx = e.getX(); prevy = e.getY(); mdtrans.setToTranslation(prevx * (1.0F - rescalew), prevy * (1.0F - rescalew)); mdtrans.scale(rescalew, rescalew); //System.out.println("prod " + pscale * sketchdisplay.sketchlinestyle.strokew); currtrans.setTransform(mdtrans); currtrans.concatenate(orgtrans); RedoBackgroundView(); //TN.emitMessage("strokew " + sketchdisplay.sketchlinestyle.strokew + " scale " + currtrans.getScaleX()); } ///////////////////////////////////////////// public void mouseMoved(MouseEvent e) { boolean bwritecoords = (sketchdisplay.bottabbedpane.getSelectedIndex() == 2); boolean btorepaint = false; if (bmoulinactive || (momotion == M_SKET_SNAPPED)) { SetMPoint(e); if (bmoulinactive) SetMouseLine(null, moupt); if (momotion == M_SKET_SNAPPED) selrect.setRect(e.getX() - SELECTWINDOWPIX, e.getY() - SELECTWINDOWPIX, SELECTWINDOWPIX * 2, SELECTWINDOWPIX * 2); // movement not in a drag. else if ((momotion != M_SKET) && sketchdisplay.miTabletMouse.isSelected() && (moulinmleng > MOVERELEASEPIX)) EndCurve(null); btorepaint = true; } else if (bwritecoords || sketchdisplay.selectedsubsetstruct.elevset.bIsElevStruct) SetMPoint(e); if (bwritecoords) { sketchdisplay.infopanel.tfmousex.setText(String.valueOf(((float)moupt.getX() / TN.CENTRELINE_MAGNIFICATION) + tsketch.sketchLocOffset.x)); sketchdisplay.infopanel.tfmousey.setText(String.valueOf((-(float)moupt.getY() / TN.CENTRELINE_MAGNIFICATION) + tsketch.sketchLocOffset.y)); if (bmoulinactive) { float x = (((float)moupt.getX() - (float)moulin.getX1()) / TN.CENTRELINE_MAGNIFICATION); float y = (((float)moupt.getY() - (float)moulin.getY1()) / TN.CENTRELINE_MAGNIFICATION); double distance = java.lang.Math.sqrt(x * x + y * y); double bearing = java.lang.Math.toDegrees(java.lang.Math.atan2(x, -y)); sketchdisplay.infopanel.tfdistance.setText(String.format("%.2f%n", distance)); if (bearing > 0) sketchdisplay.infopanel.tfbearing.setText(String.format("%.1f%n", bearing)); else sketchdisplay.infopanel.tfbearing.setText(String.format("%.1f%n", 360 + bearing)); } else { sketchdisplay.infopanel.tfbearing.setText("-"); sketchdisplay.infopanel.tfdistance.setText("-"); } } if (sketchdisplay.selectedsubsetstruct.elevset.bIsElevStruct) { sketchdisplay.selectedsubsetstruct.elevset.AlongCursorMark(elevarrow, elevpoint, moupt); btorepaint = true; if (sketchdisplay.bottabbedpane.getSelectedIndex() == 4) sketchdisplay.secondrender.repaint(); } if (btorepaint) repaint(); } public void mouseClicked(MouseEvent e) {;} public void mouseEntered(MouseEvent e) {;}; public void mouseExited(MouseEvent e) {;}; ///////////////////////////////////////////// void BackSelUndo() { if ((currgenpath != null) && bmoulinactive) { if (currgenpath.nlines >= 1) { Point2D bpt = currgenpath.BackOne(); SetMouseLine(bpt, null); } else { ClearSelection(true); // drop the line entirely repaint(); } } else if (!vactivepaths.isEmpty() && (nvactivepathcomponents == -1)) RemoveVActivePath(vactivepaths.get(vactivepaths.size() - 1)); // very crude undo of one change -- just swaps it in. Later we can add in an undo stack and a position in it. else { CommitPathChanges(tsketch.pthstoaddSaved, tsketch.pthstoremoveSaved); RedrawBackgroundView(); } } ///////////////////////////////////////////// Set MakeTotalSelList() { Set opselset = new HashSet(); if ((currgenpath != null) && (currgenpath.pnend != null)) opselset.add(currgenpath); if (currselarea != null) { for (RefPathO rpo : currselarea.refpaths) opselset.add(rpo.op); for (ConnectiveComponentAreas cca : currselarea.ccalist) { opselset.addAll(cca.vconnpaths); opselset.addAll(cca.vconnpathsrem); } // not select bits of centreline that were only later allocated by z because they didn't fit match any of the areas so far for (int i = 0; i < currselarea.nconnpathremaining; i++) opselset.add(currselarea.connpathrootscen.get(i)); } if (nvactivepathcomponents != -1) { int a = vactivepathcomponentpairs[ivactivepathcomponents*2]; int b = vactivepathcomponentpairs[ivactivepathcomponents*2+1]; //System.out.println("a="+a+" b="+b+" vactivepaths,size()="+vactivepaths.size()); for (int i = a; i < b; i++) opselset.add(vactivepaths.get(i)); } else opselset.addAll(vactivepaths); return opselset; } ///////////////////////////////////////////// int DAddPath(OnePath op) { op.SetSubsetAttrs(sketchdisplay.subsetpanel.sascurrent, sketchdisplay.sketchlinestyle.pthstyleareasigtab.sketchframedefCopied); tsvpathsviz.add(op); tsketch.rbounds.add(op.getBounds(null)); int res = tsketch.TAddPath(op, tsvnodesviz); if (sketchdisplay.selectedsubsetstruct.elevset.selevsubset != null) { sketchdisplay.selectedsubsetstruct.elevset.AddRemovePath(op, true); sketchdisplay.selectedsubsetstruct.elevset.SetIsElevStruct(true); } SketchChanged(SC_CHANGE_STRUCTURE); return res; } ///////////////////////////////////////////// void DRemovePath(OnePath path) { tsvpathsviz.remove(path); if (sketchdisplay.selectedsubsetstruct.elevset.selevsubset != null) { sketchdisplay.selectedsubsetstruct.elevset.AddRemovePath(path, false); // this doesn't work if we change the linetype (eg from the centreline) before deleting sketchdisplay.selectedsubsetstruct.elevset.SetIsElevStruct(true); } if (tsketch.TRemovePath(path, tsvareasviz, tsvnodesviz)) { SketchChanged(SC_CHANGE_STRUCTURE); boolean bupdatebicox = false; if (tsketch.opframebackgrounddrag == path) { tsketch.opframebackgrounddrag = null; bupdatebicox = true; } if (tsvpathsframesimages.remove(path)) bupdatebicox = true; if (tsvpathsframessubsets.remove(path)) bupdatebicox = true; if (tspathssurvexlabel.remove(path)) { sketchdisplay.acaPreviewLabelWireframe.setEnabled(!tspathssurvexlabel.isEmpty()); sketchdisplay.acaImportLabelCentreline.setEnabled(!tspathssurvexlabel.isEmpty()); } if (bupdatebicox && (sketchdisplay.bottabbedpane.getSelectedIndex() == 1)) sketchdisplay.backgroundpanel.UpdateBackimageCombobox(2); } } ///////////////////////////////////////////// void DeleteSel() { CollapseVActivePathComponent(); Set opselset = MakeTotalSelList(); List pthstoremove = new ArrayList(); for (OnePath op : opselset) { if ((op.linestyle != SketchLineStyle.SLS_CENTRELINE) || sketchdisplay.miDeleteCentrelines.isSelected()) pthstoremove.add(op); } if (!pthstoremove.isEmpty()) { CommitPathChanges(pthstoremove, null); RedrawBackgroundView(); } else { ClearSelection(true); repaint(); } } ///////////////////////////////////////////// static int SC_CHANGE_STRUCTURE = 100; static int SC_CHANGE_AREAS = 101; static int SC_CHANGE_SYMBOLS = 102; static int SC_CHANGE_PATHS = 103; static int SC_CHANGE_SAS = 104; static int SC_CHANGE_SAS_SYMBOLS_SAME = 106; static int SC_CHANGE_BACKGROUNDIMAGE = 105; static int SC_UPDATE_ZNODES = 110; static int SC_UPDATE_AREAS = 111; static int SC_UPDATE_SYMBOLS = 112; static int SC_UPDATE_NONE = 113; static int SC_UPDATE_ALL = 115; static int SC_UPDATE_ALL_BUT_SYMBOLS = 116; // allows for calling during frame sketch updates // ought to be moved to close to OneSketch.UpdateSomething static void SketchChangedStatic(int scchangetyp, OneSketch tsketch, SketchDisplay sketchdisplay) { // case of changing the actual file which needs to be saved if (!tsketch.bsketchfilechanged && ((scchangetyp == SC_CHANGE_STRUCTURE) || (scchangetyp == SC_CHANGE_AREAS) || (scchangetyp == SC_CHANGE_SYMBOLS) || (scchangetyp == SC_CHANGE_PATHS) || (scchangetyp == SC_CHANGE_BACKGROUNDIMAGE))) { sketchdisplay.mainbox.tunnelfilelist.repaint(); tsketch.bsketchfilechanged = true; tsketch.isketchchangecount++; } if (scchangetyp == SC_CHANGE_SAS) scchangetyp = SC_CHANGE_SYMBOLS; if (scchangetyp == SC_CHANGE_STRUCTURE) tsketch.bZonnodesUpdated = false; else if (scchangetyp == SC_UPDATE_ZNODES) tsketch.bZonnodesUpdated = true; if ((scchangetyp == SC_CHANGE_STRUCTURE) || (scchangetyp == SC_CHANGE_AREAS) || (scchangetyp == SC_UPDATE_ZNODES)) tsketch.bSAreasUpdated = false; else if (scchangetyp == SC_UPDATE_AREAS) tsketch.bSAreasUpdated = true; if ((scchangetyp == SC_CHANGE_STRUCTURE) || (scchangetyp == SC_CHANGE_AREAS) || (scchangetyp == SC_CHANGE_SYMBOLS) || (scchangetyp == SC_UPDATE_AREAS)) tsketch.bSymbolLayoutUpdated = false; else if (scchangetyp == SC_UPDATE_SYMBOLS) tsketch.bSymbolLayoutUpdated = true; if (sketchdisplay != null) { sketchdisplay.acaSetZonnodes.setEnabled(!tsketch.bZonnodesUpdated); sketchdisplay.acaUpdateSAreas.setEnabled(!tsketch.bSAreasUpdated); sketchdisplay.acaUpdateSymbolLayout.setEnabled(!tsketch.bSymbolLayoutUpdated); } } ///////////////////////////////////////////// void SketchChanged(int scchangetyp) { SketchChangedStatic(scchangetyp, tsketch, sketchdisplay); } ///////////////////////////////////////////// void UpdateZNodes() { tsketch.UpdateSomething(SC_UPDATE_ZNODES, true); SketchChanged(SC_UPDATE_ZNODES); } ///////////////////////////////////////////// void UpdateSAreas() { tsketch.UpdateSomething(SC_UPDATE_AREAS, true); sketchdisplay.mainbox.UpdateSketchFrames(tsketch, SketchGraphics.SC_UPDATE_NONE); SketchChanged(SC_UPDATE_AREAS); sketchdisplay.selectedsubsetstruct.SetSubsetVisibleCodeStringsT(sketchdisplay.selectedsubsetstruct.elevset.selevsubset, tsketch); // put back the same subset (hack!) RedoBackgroundView(); } ///////////////////////////////////////////// void GUpdateSymbolLayout(boolean bAllSymbols, JProgressBar visiprogressbar) { visiprogressbar.setString("symbols"); visiprogressbar.setStringPainted(true); List lvconncommutual = new ArrayList(); GraphicsAbstraction ga = new GraphicsAbstraction(mainGraphics); for (MutualComponentArea mca : tsketch.sksya.vconncommutual) { if (bAllSymbols || (!mca.bsymbollaidout && ((windowrect == null) || mca.hit(ga, windowrect)))) lvconncommutual.add(mca); } sketchdisplay.mainbox.symbollayoutprocess.UpdateSymbolLayout(lvconncommutual, visiprogressbar); } ///////////////////////////////////////////// void FuseNodesS(List pthstoremove, List pthstoadd, OnePathNode wpnstart, OnePathNode wpnend, OnePath opexcl1, OnePath opexcl2, boolean bShearWarp) { // find all paths that link into the first node and warp them to the second. // must be done backwards due to messing of the array // could have done this with one invocation of WarpPiece that is reused for (int i = tsketch.vpaths.size() - 1; i >= 0; i--) { OnePath op = tsketch.vpaths.get(i); if (((op.pnstart == wpnstart) || (op.pnend == wpnstart)) && ((op != opexcl1) && (op != opexcl2))) { pthstoremove.add(op); WarpPiece ewp = new WarpPiece(wpnstart, wpnend, op, (bShearWarp ? WarpPiece.WARP_SHEARWARP : WarpPiece.WARP_NORMALWARP)); OnePath opw = ewp.WarpPathS(op); pthstoadd.add(opw); } } // copy over the altitude of this node if (wpnstart.IsCentrelineNode()) { //assert wpnend.IsCentrelineNode(); //assert wpnend.pnstationlabel.equals(wpnstart.pnstationlabel); wpnend.zalt = wpnstart.zalt; } } ///////////////////////////////////////////// // should be able to in-line the DAddPath and DRemovePaths to this function // then commit onto an undo stack in the sketch boolean CommitPathChanges(List pthstoremove, List pthstoadd) { TN.emitMessage("Committing to delete " + (pthstoremove == null ? 0 : pthstoremove.size()) + " paths and add " + (pthstoadd == null ? 0 : pthstoadd.size()) + " paths"); ClearSelection(true); // causes a repaint (could be a problem) if (!bEditable) return false; // the single undo element (which cycles automatically when we reverse the two in the BackSelUndo function) tsketch.pthstoremoveSaved = pthstoremove; tsketch.pthstoaddSaved = pthstoadd; if (pthstoremove != null) { for (OnePath op : pthstoremove) { assert tsketch.vpaths.contains(op); // assert (pthstoadd == null) || !pthstoadd.contains(op); // violated in the pitch undercut case sketchdisplay.mainbox.netconnection.netcommitpathchange(op, "remove", tsketch); DRemovePath(op); } } if (pthstoadd != null) { for (OnePath op : pthstoadd) { assert !tsketch.vpaths.contains(op); DAddPath(op); sketchdisplay.mainbox.netconnection.netcommitpathchange(op, "add", tsketch); if ((op.linestyle == SketchLineStyle.SLS_CENTRELINE) && (op.plabedl != null)) op.UpdateStationLabelsFromCentreline(); } } SketchChanged(SC_CHANGE_STRUCTURE); // RedrawBackgroundView(); // move to outer calls so it can be deferred if ((pthstoadd != null) && (pthstoadd.size() == 1)) { currgenpath = pthstoadd.get(0); ObserveSelection(currgenpath, null, 6); } // else select everything into the vactivepaths assert OnePathNode.CheckAllPathCounts(tsketch.vnodes, tsketch.vpaths); return true; } ///////////////////////////////////////////// OnePathNode TranslatedNode(OnePathNode opn, List pthnodestomove, List pthnodesmoved, double vx, double vy) { assert pthnodestomove.size() == pthnodesmoved.size(); int i = pthnodestomove.indexOf(opn); if (i != -1) return pthnodesmoved.get(i); OnePathNode res = new OnePathNode((float)(opn.pn.getX() + vx), (float)(opn.pn.getY() + vy), opn.zalt); pthnodestomove.add(opn); pthnodesmoved.add(res); return res; } ///////////////////////////////////////////// boolean FuseTranslate(OnePath lcurrgenpath, int a, int b) { List pthstoremove = new ArrayList(); for (int i = a; i < b; i++) pthstoremove.add(vactivepaths.get(i)); List pthnodestomove = new ArrayList(); List pthnodesmoved = new ArrayList(); // parallel array double vx = lcurrgenpath.pnend.pn.getX() - lcurrgenpath.pnstart.pn.getX(); double vy = lcurrgenpath.pnend.pn.getY() - lcurrgenpath.pnstart.pn.getY(); List pthstoadd = new ArrayList(); for (OnePath op : pthstoremove) { if (op == lcurrgenpath) continue; OnePathNode nopnstart = TranslatedNode(op.pnstart, pthnodestomove, pthnodesmoved, vx, vy); OnePathNode nopnend = TranslatedNode(op.pnend, pthnodestomove, pthnodesmoved, vx, vy); float[] pco = op.GetCoords(); OnePath nop = new OnePath(nopnstart); for (int i = 1; i < op.nlines; i++) nop.LineTo((float)(pco[i * 2] + vx), (float)(pco[i * 2 + 1] + vy)); nop.EndPath(nopnend); nop.CopyPathAttributes(op); pthstoadd.add(nop); } CommitPathChanges(pthstoremove, pthstoadd); RedrawBackgroundView(); System.out.println("Do fuse translate"); return true; } ///////////////////////////////////////////// boolean FuseTwoEdges(OnePath op1, OnePath op2) { // work out node connection. OnePathNode pnconnect = null; if ((op1.pnend == op2.pnstart) || (op1.pnend == op2.pnend)) pnconnect = op1.pnend; else if ((op1.pnstart == op2.pnstart) || (op1.pnstart == op2.pnend)) pnconnect = op1.pnstart; else return TN.emitWarning("Must have connecting paths"); // decide whether to fuse if properties agree if ((pnconnect == null) || (pnconnect.pathcount != 2) || (op1.linestyle != op2.linestyle) || (op1.linestyle == SketchLineStyle.SLS_CENTRELINE)) return TN.emitWarning("Fusing paths must agree"); OnePath opf = op1.FuseNode(pnconnect, op2); opf.vssubsets.addAll(op1.vssubsets); // add without duplicates for (String ssub : op2.vssubsets) { if (!opf.vssubsets.contains(ssub)) opf.vssubsets.add(ssub); } // just runs in parallel, duplicates don't matter opf.vssubsetattrs.addAll(op1.vssubsetattrs); opf.vssubsetattrs.addAll(op2.vssubsetattrs); opf.bpathvisiblesubset = (op1.bpathvisiblesubset || op2.bpathvisiblesubset); List pthstoremove = new ArrayList(); List pthstoadd = new ArrayList(); // delete this warped path pthstoremove.add(op1); pthstoremove.add(op2); pthstoadd.add(opf); CommitPathChanges(pthstoremove, pthstoadd); RedrawBackgroundView(); return true; } ///////////////////////////////////////////// boolean FuseCurrent(boolean bShearWarp) { // FuseTranslate situation if ((nvactivepathcomponents != -1) && (ivactivepathcomponents == ivactivepathcomponents_wholeselection) && (icurrgenvactivepath != -1) && !bmoulinactive) { OnePath lcurrgenpath = vactivepaths.get(icurrgenvactivepath); if ((lcurrgenpath.linestyle == SketchLineStyle.SLS_CENTRELINE) || (lcurrgenpath.nlines != 1) || (lcurrgenpath.pnend.pathcount != 1) || (lcurrgenpath.pnstart.pathcount == 1)) return TN.emitWarning("Can only fuse-translate single path with simple connections"); int a = vactivepathcomponentpairs[ivactivepathcomponents*2]; int b = vactivepathcomponentpairs[ivactivepathcomponents*2+1]; return FuseTranslate(lcurrgenpath, a, b); } CollapseVActivePathComponent(); if (vactivepaths.size() >= 3) return TN.emitWarning("Fuse works on single or pair of paths"); // fuse two edges (in a single selected chain) if (vactivepaths.size() == 2) return FuseTwoEdges(vactivepaths.get(0), vactivepaths.get(1)); // fuse along a single edge else { if (bmoulinactive) return TN.emitWarning("Can't fuse active path"); // the path to warp along OnePath warppath; if ((vactivepaths.size() == 1) && (currgenpath == null)) warppath = vactivepaths.get(0); else if (currgenpath != null) warppath = currgenpath; else return TN.emitWarning("Must have single path selected for fuse"); if ((warppath.nlines > 1) || (warppath.linestyle == SketchLineStyle.SLS_CENTRELINE) || (warppath.pnstart == currgenpath.pnend)) return TN.emitWarning("Must have straight non-centreline line selected"); if (warppath.pnstart.IsCentrelineNode() && warppath.pnend.IsCentrelineNode()) return TN.emitWarning("Can't fuse two centreline nodes"); if (!bEditable) return TN.emitWarning("Sketch not editable"); if (warppath.pnstart.pathcount == 1) return TN.emitWarning("Can't fuse nothing across"); // now fuse the nodes, and behave differently if it's an elevation node // the default fusing is forced on an elevation node by making the warppath a ceiling boundary List elevcenconn = (warppath.linestyle != SketchLineStyle.SLS_CEILINGBOUND ? ElevSet.IsElevationNode(warppath.pnstart) : null); List pthstoremove = new ArrayList(); List pthstoadd = new ArrayList(); if (elevcenconn != null) { System.out.println("asdasda " + elevcenconn.size()); ElevWarp elevwarp = new ElevWarp(); if (!elevwarp.MakeElevWarp(elevcenconn, tsketch.vpaths)) return TN.emitWarning("Failed to account for all elevation structures connecting to this node"); elevwarp.MakeWarpPathPieceMap(warppath); elevwarp.MakeWarpPathNodeslists(); elevwarp.WarpAllPaths(pthstoremove, pthstoadd, warppath); assert !warppath.pnstart.IsCentrelineNode(); assert pthstoadd.size() == pthstoremove.size(); } else FuseNodesS(pthstoremove, pthstoadd, warppath.pnstart, warppath.pnend, warppath, null, bShearWarp); // separate out the warp path first so when we do an undo, we don't get it back List pthstoremovewarppath = new ArrayList(); pthstoremovewarppath.add(warppath); CommitPathChanges(pthstoremovewarppath, null); //pthstoremove.add(warppath); CommitPathChanges(pthstoremove, pthstoadd); if (warppath.pnstart.pathcount != 0) TN.emitError("Warp path failed to carry all connections from its node"); RedrawBackgroundView(); return true; } } ///////////////////////////////////////////// boolean Makesquare() { Set opselset = MakeTotalSelList(); int nxalign = 0; int nyalign = 0; List pthssquare = new ArrayList(); List pthsnotsquare = new ArrayList(); for (OnePath op : opselset) { double xdiff = Math.abs(op.pnend.pn.getX() - op.pnstart.pn.getX()); double ydiff = Math.abs(op.pnend.pn.getY() - op.pnstart.pn.getY()); if ((xdiff == 0.0) || (ydiff == 0.0)) pthssquare.add(op); else pthsnotsquare.add(op); if (xdiff > ydiff) nxalign++; else nyalign++; } System.out.println("sel="+opselset.size()+" xyalign "+nxalign+" "+nyalign+" ss "+pthssquare.size()+" "+pthsnotsquare.size()); if ((nxalign != 0) && (nyalign != 0)) return TN.emitWarning("Selected paths not consistently aligned"); boolean bxfixed = (nyalign != 0); if ((bxfixed ? nyalign : nxalign) == 0) return TN.emitWarning("No paths selected subject to make square"); if (pthsnotsquare.size() == 0) return TN.emitWarning("All paths already square"); double wval = -999.0; if (pthssquare.size() != 0) { int i = 0; for (OnePath op : pthssquare) { double lwval = (bxfixed ? op.pnend.pn.getX() : op.pnend.pn.getY()); if (i == 0) wval = lwval; else if (wval != lwval) return TN.emitWarning("Square paths not aligned (move the one you want to move out of line first)"); i++; } } else { double sumwval = 0.0; for (OnePath op : pthsnotsquare) sumwval += (bxfixed ? op.pnstart.pn.getX() : op.pnstart.pn.getY()) + (bxfixed ? op.pnend.pn.getX() : op.pnend.pn.getY()); wval = sumwval / (2 * pthsnotsquare.size()); } // now produce the aligned array of nodes to warp List pthnodesfrom = new ArrayList(); for (OnePath op : pthsnotsquare) { if (!pthnodesfrom.contains(op.pnstart)) pthnodesfrom.add(op.pnstart); if (!pthnodesfrom.contains(op.pnend)) pthnodesfrom.add(op.pnend); } // now fuse each node in turn (may attempt to do a batch job in future, but tricky) ClearSelection(true); for (OnePathNode opn : pthnodesfrom) { OnePathNode opnsquare = new OnePathNode((float)(bxfixed ? wval : opn.pn.getX()), (float)(!bxfixed ? wval : opn.pn.getY()), opn.zalt); List pthstoremove = new ArrayList(); List pthstoadd = new ArrayList(); FuseNodesS(pthstoremove, pthstoadd, opn, opnsquare, null, null, false); CommitPathChanges(pthstoremove, pthstoadd); RedrawBackgroundView(); } return true; } ///////////////////////////////////////////// // and finds the components which the selection separates boolean SelectConnectedSetsFromSelection() { // cycle through the components if (nvactivepathcomponents != -1) { ivactivepathcomponents = (ivactivepathcomponents + 1 == nvactivepathcomponents ? 0 : ivactivepathcomponents + 1); System.out.println("ivactivepathcomponents " + ivactivepathcomponents); return true; } OnePath lcurrgenpath = (((currgenpath != null) && (currgenpath.pnend != null)) ? currgenpath : null); CollapseVActivePathComponent(); Set vpathssel = MakeTotalSelList(); if (vpathssel.isEmpty()) return TN.emitWarning("Must have something selected"); Set vpathnodessel = new HashSet(); for (OnePath op : vpathssel) { vpathnodessel.add(op.pnstart); vpathnodessel.add(op.pnend); } Set vpathsoffsel = new HashSet(); RefPathO srefpathconn = new RefPathO(); for (OnePathNode opn : vpathnodessel) { srefpathconn.ccopy(opn.ropconn); do { if (!vpathssel.contains(srefpathconn.op)) vpathsoffsel.add(srefpathconn.op); } while (!srefpathconn.AdvanceRoundToNode(opn.ropconn)); } List< Set > vpathscomponents = new ArrayList< Set >(); Set vpathscomponentsiremains = new HashSet(tsketch.vpaths); vpathscomponentsiremains.removeAll(vpathssel); List vpathnodesstack = new ArrayList(); Set vpathnodeschecked = new HashSet(); for (OnePath op : vpathsoffsel) { if (!vpathscomponentsiremains.contains(op)) continue; assert vpathnodesstack.isEmpty() && vpathnodeschecked.isEmpty(); Set vpathscomponent = new HashSet(); vpathscomponent.add(op); if (!vpathnodessel.contains(op.pnstart)) vpathnodesstack.add(op.pnstart); if (!vpathnodessel.contains(op.pnend)) vpathnodesstack.add(op.pnend); while (!vpathnodesstack.isEmpty()) { OnePathNode opn = vpathnodesstack.remove(vpathnodesstack.size() - 1); srefpathconn.ccopy(opn.ropconn); vpathnodeschecked.add(opn); do { assert !vpathscomponents.contains(srefpathconn.op); vpathscomponent.add(srefpathconn.op); OnePathNode fopn = srefpathconn.FromNode(); if (!vpathnodessel.contains(fopn) && !vpathnodeschecked.contains(fopn)) vpathnodesstack.add(fopn); } while (!srefpathconn.AdvanceRoundToNode(opn.ropconn)); } vpathnodeschecked.clear(); vpathscomponents.add(vpathscomponent); vpathscomponentsiremains.removeAll(vpathscomponent); } ClearSelection(true); assert vactivepaths.isEmpty(); if (vpathscomponents.size()*2 + 4 > vactivepathcomponentpairs.length) vactivepathcomponentpairs = new int[vpathscomponents.size()*2 + 10]; nvactivepathcomponents = 0; for (Set vpathscomponent : vpathscomponents) { vactivepathcomponentpairs[nvactivepathcomponents*2] = vactivepaths.size(); vactivepaths.addAll(vpathscomponent); vactivepathcomponentpairs[nvactivepathcomponents*2+1] = vactivepaths.size(); nvactivepathcomponents++; } // original selection group vactivepathcomponentpairs[nvactivepathcomponents*2] = vactivepaths.size(); vactivepaths.addAll(vpathssel); vactivepathcomponentpairs[nvactivepathcomponents*2+1] = vactivepaths.size(); nvactivepathcomponents++; // whole selection vactivepathcomponentpairs[nvactivepathcomponents*2] = 0; vactivepathcomponentpairs[nvactivepathcomponents*2+1] = vactivepaths.size(); ivactivepathcomponents = nvactivepathcomponents; // starting point ivactivepathcomponents_wholeselection = nvactivepathcomponents; nvactivepathcomponents++; // complement of selected set if (!vpathscomponentsiremains.isEmpty()) { vactivepathcomponentpairs[nvactivepathcomponents*2] = vactivepaths.size(); vactivepaths.addAll(vpathscomponentsiremains); vactivepathcomponentpairs[nvactivepathcomponents*2+1] = vactivepaths.size(); nvactivepathcomponents++; } vactivepathsnodecounts.clear(); // not useful here icurrgenvactivepath = (lcurrgenpath != null ? vactivepaths.indexOf(lcurrgenpath) : -1); System.out.println("nvactivepathcomponentsnvactivepathcomponents " + nvactivepathcomponents); //vactivepathsnodecounts.add(path.pnstart); //vactivepathsnodecounts.add(path.pnend); //Collections.sort(vactivepathsnodecounts); return true; } ///////////////////////////////////////////// boolean ReflectCurrent() { // cases for throwing out the individual edge if (!vactivepaths.isEmpty() || (currgenpath == null) || bmoulinactive || (currgenpath.linestyle == SketchLineStyle.SLS_CENTRELINE)) return TN.emitWarning("Can only reflect single selective path that's not a centreline"); OnePath nop = new OnePath(currgenpath.pnend); float[] pco = currgenpath.GetCoords(); for (int i = currgenpath.nlines - 1; i >= 1; i--) nop.LineTo(pco[i * 2], pco[i * 2 + 1]); nop.EndPath(currgenpath.pnstart); nop.CopyPathAttributes(currgenpath); List pthstoremove = new ArrayList(); List pthstoadd = new ArrayList(); pthstoremove.add(currgenpath); pthstoadd.add(nop); CommitPathChanges(pthstoremove, pthstoadd); RedrawBackgroundView(); return true; } ///////////////////////////////////////////// void SelectSingle(OnePath op) { ClearSelection(true); repaint(); currgenpath = op; ObserveSelection(currgenpath, null, 8); } ///////////////////////////////////////////// // if the current selection is a line segment then we make it a centreline type. void SetAsAxis() { if (!tsketch.bSymbolType) TN.emitWarning("Set axis only valid for symbol type."); if (!bmoulinactive && (currgenpath != null) && (currgenpath.nlines == 1)) { OnePath apath = tsketch.GetAxisPath(); if (apath != null) apath.linestyle = SketchLineStyle.SLS_DETAIL; currgenpath.linestyle = SketchLineStyle.SLS_CENTRELINE; TN.emitMessage("Axis Set"); ClearSelection(true); RedrawBackgroundView(); } } ///////////////////////////////////////////// boolean MakePitchUndercut() { if (bmoulinactive || (currgenpath == null) || (currgenpath.linestyle != SketchLineStyle.SLS_PITCHBOUND)) return TN.emitWarning("Pitch undercut must have pitch boundary selected."); OnePath oppitch = currgenpath; List pthstoremove = new ArrayList(); List pthstoadd = new ArrayList(); OnePath opddconnstart = oppitch.pnstart.GetDropDownConnPath(); if (opddconnstart.pnend.pathcount == 0) // always true when adding a new one (not in the unlikely event of having found a dropdown connpath already, if we are working in segments) { opddconnstart.vssubsets.addAll(oppitch.vssubsets); pthstoadd.add(opddconnstart); } OnePath opddconnend = oppitch.pnend.GetDropDownConnPath(); if (opddconnend.pnend.pathcount == 0) { opddconnend.vssubsets.addAll(oppitch.vssubsets); pthstoadd.add(opddconnend); } // now make the invisible line OnePath opinv = new OnePath(); opinv.pnstart = opddconnstart.pnend; opinv.pnend = opddconnend.pnend; opinv.linestyle = SketchLineStyle.SLS_INVISIBLE; opinv.vssubsets.addAll(oppitch.vssubsets); opinv.gp = (GeneralPath)oppitch.gp.clone(); opinv.nlines = oppitch.nlines; opinv.linelength = oppitch.linelength; opinv.bSplined = oppitch.bSplined; opinv.bWantSplined = oppitch.bWantSplined; pthstoadd.add(opinv); // remove and add the current path to be removed and added so it appears on top pthstoremove.add(oppitch); pthstoadd.add(oppitch); CommitPathChanges(pthstoremove, pthstoadd); RedrawBackgroundView(); return true; } ///////////////////////////////////////////// void ClearSelection(boolean bupdatepathparameters) { if (bupdatepathparameters) { if (sketchdisplay.subsetpanel.sascurrent != null) sketchdisplay.sketchlinestyle.GoSetParametersCurrPath(); // this copies over anything that was missed else TN.emitWarning("sascurrent is null when updating parameters"); } currgenpath = null; currselarea = null; vactivepaths.clear(); vactivepathsnodecounts.clear(); nvactivepathcomponents = -1; ivactivepathcomponents = -1; bmoulinactive = false; // newly added ObserveSelection(null, null, 7); //repaint(); } ///////////////////////////////////////////// void CollapseVActivePathComponent() { if (nvactivepathcomponents != -1) { // would like to do this with two remove range functions, but don't have the docs on this machine int a = vactivepathcomponentpairs[ivactivepathcomponents*2]; int b = vactivepathcomponentpairs[ivactivepathcomponents*2+1]; for (int i = a; i < b; i++) vactivepaths.set(i - a, vactivepaths.get(i)); while (vactivepaths.size() > b - a) vactivepaths.remove(vactivepaths.size() - 1); } if (nvactivepathcomponents != -1) { for (OnePath op : vactivepaths) { vactivepathsnodecounts.add(op.pnstart); vactivepathsnodecounts.add(op.pnend); } Collections.sort(vactivepathsnodecounts); nvactivepathcomponents = -1; } } ///////////////////////////////////////////// void RemoveVActivePath(OnePath path) { assert vactivepaths.contains(path); vactivepaths.remove(path); vactivepathsnodecounts.remove(path.pnstart); vactivepathsnodecounts.remove(path.pnend); } ///////////////////////////////////////////// void AddVActivePath(OnePath path) { vactivepaths.add(path); vactivepathsnodecounts.add(path.pnstart); vactivepathsnodecounts.add(path.pnend); Collections.sort(vactivepathsnodecounts); } ///////////////////////////////////////////// // works from the known values in the class to break the current path boolean SplitCurrpathNode() { OnePath nop1 = new OnePath(currgenpath.pnstart); float[] pco = currgenpath.GetCoords(); for (int i = 1; i < linesnap_t; i++) // < on the float simulates ceil nop1.LineTo(pco[i * 2], pco[i * 2 + 1]); nop1.EndPath(currpathnode); nop1.CopyPathAttributes(currgenpath); OnePath nop2 = new OnePath(currpathnode); for (int i = (int)(linesnap_t + 1.0); i < currgenpath.nlines; i++) nop2.LineTo(pco[i * 2], pco[i * 2 + 1]); nop2.EndPath(currgenpath.pnend); nop2.CopyPathAttributes(currgenpath); List pthstoremove = new ArrayList(); List pthstoadd = new ArrayList(); pthstoremove.add(currgenpath); pthstoadd.add(nop1); pthstoadd.add(nop2); CommitPathChanges(pthstoremove, pthstoadd); RedrawBackgroundView(); return true; } ///////////////////////////////////////////// public void Scale(float sca) { // set the pre transformation mdtrans.setToTranslation(csize.width / 2, csize.height / 2); mdtrans.scale(sca, sca); mdtrans.translate(-csize.width / 2, -csize.height / 2); orgtrans.setTransform(currtrans); currtrans.setTransform(mdtrans); currtrans.concatenate(orgtrans); RedoBackgroundView(); } ///////////////////////////////////////////// // new stuff for tilting and producing a drawing plane public void TiltView(double ltiltdeg) { // set the pre transformation mdtrans.setToTranslation(csize.width / 2, csize.height / 2); mdtrans.scale(1.0F, (ltiltdeg > 0.0 ? 0.5F : 2.0F)); mdtrans.translate(-csize.width / 2, -csize.height / 2); orgtrans.setTransform(currtrans); currtrans.setTransform(mdtrans); currtrans.concatenate(orgtrans); UpdateTilt(false); RedoBackgroundView(); } ///////////////////////////////////////////// double scaTilt = 1.0; // of currtrans AffineTransform currtilttrans = new AffineTransform(); void UpdateTilt(boolean bforce) { // derive the scatilt from currtrans (not ideal, but keeps it consistent) double scaX = Math.sqrt(currtrans.getScaleX()*currtrans.getScaleX() + currtrans.getShearX()*currtrans.getShearX()); double scaY = Math.sqrt(currtrans.getScaleY()*currtrans.getScaleY() + currtrans.getShearY()*currtrans.getShearY()); scaTilt = scaY / scaX; assert scaTilt <= 1.001; if (scaTilt > 0.999) scaTilt = 1.0; if (!bforce && currtilttrans.equals(currtrans)) return; if (!sketchdisplay.miShowTilt.isSelected()) return; // save time currtilttrans.setTransform(currtrans); // apply to the tilted lifted paths System.out.println("scscT "+scaTilt+" "+currtrans.getScaleY() / currtrans.getScaleX()); // tilt and undo the scale in x axis (the real scale) Don't know how the rotating is working without doing this double scaTiltZ = scaX * Math.sqrt(1.0 - scaTilt*scaTilt); //(scaTilt != 1.0 ? Math.sin(Math.acos(scaTilt)) : 0.0); System.out.println("TIIILT " +scaX+" "+ scaTilt + " "+scaTiltZ+ " "); for (OnePath op : tsketch.vpaths) { if ((op.linestyle != SketchLineStyle.SLS_INVISIBLE) && (op.linestyle != SketchLineStyle.SLS_CONNECTIVE)) op.MakeTilted(sketchdisplay.ztiltpanel.zlothinnedvisible, sketchdisplay.ztiltpanel.zhithinnedvisible, scaTiltZ, currtrans); } } ///////////////////////////////////////////// public void Translate(double xprop, double yprop) { // set the pre transformation mdtrans.setToTranslation(csize.width * xprop, csize.height * yprop); orgtrans.setTransform(currtrans); currtrans.setTransform(mdtrans); currtrans.concatenate(orgtrans); RedoBackgroundView(); } ///////////////////////////////////////////// public void Rotate(float degrees) { //double scaTilt = currtrans.getScaleY() / currtrans.getScaleX(); mdtrans.setToScale(1.0, scaTilt); mdtrans.rotate(Math.toRadians(degrees), csize.width / 2, csize.height / (scaTilt * 2)); mdtrans.scale(1.0, 1.0 / scaTilt); orgtrans.setTransform(currtrans); currtrans.setTransform(mdtrans); currtrans.concatenate(orgtrans); RedoBackgroundView(); } ///////////////////////////////////////////// ///////////////////////////////////////////// ///////////////////////////////////////////// // dragging out a curve ///////////////////////////////////////////// void StartCurve(OnePathNode pnstart) { currgenpath = new OnePath(pnstart); sketchdisplay.sketchlinestyle.SetParametersFromBoxes(currgenpath); SetMouseLine(pnstart.pn, moupt); bmoulinactive = true; } ///////////////////////////////////////////// void LineToCurve() { if (moulinmleng != 0) { currgenpath.IntermedLines(moupath, nmoupathpieces); currgenpath.LineTo((float)moupt.getX(), (float)moupt.getY()); SetMouseLine(moupt, moupt); } } ///////////////////////////////////////////// void EndCurve(OnePathNode pnend) { bmoulinactive = false; momotion = M_NONE; if (currgenpath.EndPath(pnend)) { List pthstoadd = new ArrayList(); pthstoadd.add(currgenpath); // automatically add to subsets if (sketchdisplay.miAutoAddToSubset.isSelected() || sketchdisplay.selectedsubsetstruct.elevset.bIsElevStruct) { for (String ssub : sketchdisplay.selectedsubsetstruct.vsselectedsubsetsP) sketchdisplay.subsetpanel.PutToSubset(currgenpath, ssub, true); } CommitPathChanges(null, pthstoadd); RedrawBackgroundView(); } else { currgenpath = null; } } ///////////////////////////////////////////// ///////////////////////////////////////////// double linesnap_t = -1.0; // records the location of splitting. Point2D clpt = new Point2D.Double(); ///////////////////////////////////////////// void mousePressedDragview(MouseEvent e) { // if a point is already being dragged, then this second mouse press will delete it. if ((momotion == M_DYN_DRAG) || (momotion == M_DYN_SCALE) || (momotion == M_DYN_ROT)) { momotion = M_NONE; currtrans.setTransform(orgtrans); RedoBackgroundView(); return; } orgtrans.setTransform(currtrans); //backgroundimg.orgparttrans.setTransform(backgroundimg.currparttrans); mdtrans.setToIdentity(); prevx = e.getX(); prevy = e.getY(); if (!e.isMetaDown()) { if (e.isShiftDown()) momotion = M_DYN_DRAG; else if (e.isControlDown()) momotion = M_DYN_SCALE; else if (sketchdisplay.miEnableRotate.isSelected() || sketchdisplay.miShowTilt.isSelected()) momotion = M_DYN_ROT; else momotion = M_DYN_DRAG; // was M_NONE } } ///////////////////////////////////////////// void mousePressedCtrlUp(MouseEvent e) { SetMPoint(e); // ending a path if (bmoulinactive) { LineToCurve(); if (e.isShiftDown() || ((e.getClickCount() == 2) && sketchdisplay.miEnableDoubleClick.isSelected())) EndCurve(null); } // here is where we can toggle the requirement that the shift key is held down to start a path else { if (!e.isShiftDown()) { ClearSelection(true); OnePathNode opns = new OnePathNode((float)moupt.getX(), (float)moupt.getY(), GetMidZsel()); opns.SetNodeCloseBefore(tsketch.vnodes, tsketch.vnodes.size()); StartCurve(opns); momotion = M_SKET; LineToCurve(); repaint(); } // nothing happens if shift is down when you start clicking } repaint(); } ///////////////////////////////////////////// void mousePressedEndAndStartPath(MouseEvent e) { LineToCurve(); EndCurve(null); OnePathNode opns = currgenpath.pnend; ClearSelection(true); StartCurve(opns); repaint(); } ///////////////////////////////////////////// void mousePressedSnapToNode(MouseEvent e) { SetMPoint(e); momotion = M_SKET_SNAP; linesnap_t = -1.0; selrect.setRect(e.getX() - SELECTWINDOWPIX, e.getY() - SELECTWINDOWPIX, SELECTWINDOWPIX * 2, SELECTWINDOWPIX * 2); repaint(); } ///////////////////////////////////////////// void mousePressedSplitLine(MouseEvent e) { SetMPoint(e); // the node splitting one. only on edges if shift is down(over-ride with shift down) //double scale = Math.min(currtrans.getScaleX(), currtrans.getScaleY()); double scaX = Math.sqrt(currtrans.getScaleX()*currtrans.getScaleX() + currtrans.getShearX()*currtrans.getShearX()); linesnap_t = currgenpath.ClosestPoint(moupt.getX(), moupt.getY(), 5.0 / scaX); if ((currgenpath.linestyle != SketchLineStyle.SLS_CENTRELINE) && (linesnap_t != -1.0) && (linesnap_t > 0.0) && (linesnap_t < currgenpath.nlines)) { currgenpath.Eval(clpt, null, linesnap_t); selpathnode = new OnePathNode((float)clpt.getX(), (float)clpt.getY(), GetMidZsel()); selpathnode.SetNodeCloseBefore(tsketch.vnodes, tsketch.vnodes.size()); SetMouseLine(clpt, clpt); momotion = M_SKET_SNAPPED; repaint(); } // failed to split -- get no mode. else momotion = M_NONE; } ///////////////////////////////////////////// public void mousePressed(MouseEvent e) { sketchdisplay.ztiltpanel.cbaAnimateTour.setSelected(false); //System.out.println("mouclickcount " + e.getClickCount()); //TN.emitMessage(" " + e.getModifiers() + " " + e.getModifiersEx() + "-" + (e.getModifiersEx() & MouseEvent.BUTTON2_MASK) + " " + MouseEvent.BUTTON2_MASK); //TN.emitMessage("B1 " + e.BUTTON1_MASK + " B2 " + e.BUTTON2_MASK + " B3 " + e.BUTTON3_MASK + " ALT " + e.ALT_MASK + " META " + e.META_MASK + " MetDown " + e.isMetaDown()); // are we in the whole picture dragging mode? (middle mouse button). // (if we click another mouse button while holding the middle mouse button down, we will still get in here) if (((e.getModifiersEx() & MouseEvent.BUTTON2_DOWN_MASK) != 0) || e.isAltDown()) // altdown means alt-key gets you there too. mousePressedDragview(e); // right mouse button else if ((e.getModifiersEx() & MouseEvent.BUTTON3_DOWN_MASK) != 0) { // selecting a path if (!bmoulinactive) { momotion = (e.isShiftDown() ? M_SEL_AREA : (e.isControlDown() ? M_SEL_PATH_ADD : M_SEL_PATH)); selrect.setRect(e.getX() - SELECTWINDOWPIX, e.getY() - SELECTWINDOWPIX, SELECTWINDOWPIX * 2, SELECTWINDOWPIX * 2); repaint(); // to activate the hit command. } } // bail out non-editable cases else if (!bEditable) ; // left mouse button else if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) == 0) ; // impossible // there's going to be a very special case with sket_snap. else if (!e.isControlDown()) mousePressedCtrlUp(e); else if (!e.isShiftDown()) mousePressedSnapToNode(e); else if (currgenpath == null) ; // shift and control held down else if (!bmoulinactive) mousePressedSplitLine(e); // end and continue node at same time else if (bmoulinactive) mousePressedEndAndStartPath(e); } ///////////////////////////////////////////// public void mouseDragged(MouseEvent e) { switch (momotion) { case M_DYN_DRAG: { int xv = e.getX() - prevx; int yv = e.getY() - prevy; mdtrans.setToTranslation(xv, yv); break; } case M_DYN_SCALE: { int x = e.getX(); int y = e.getY(); float rescalex, rescaley; if (false) // non-uniform scaling { rescalex = 1.0F + ((float)Math.abs(x - prevx) / csize.width) * 2.0F; if (x < prevx) rescalex = 1.0F / rescalex; rescaley = 1.0F + ((float)Math.abs(y - prevy) / csize.height) * 2.0F; if (y < prevy) rescaley = 1.0F / rescaley; } // uniform scaling in both axes when not doing background. else { int w = (x - prevx) + (prevy - y); // allow drawing in either direction float wfac = Math.max(csize.width, csize.height); float rescalew = 1.0F + ((float)Math.abs(w) / wfac) * 2.0F; if (w < 0) rescalew = 1.0F / rescalew; rescalex = rescalew; rescaley = rescalew; } mdtrans.setToTranslation(prevx * (1.0F - rescalex), prevy * (1.0F - rescaley)); mdtrans.scale(rescalex, rescaley); break; } case M_DYN_ROT: { // an effective rotation system will be difficult to do // kind of want to by making circles round the centre, // but then it's not by start point that matters. must update prevx as we move int vx = e.getX() - prevx; //double scaTilt = currtrans.getScaleY() / currtrans.getScaleX(); mdtrans.setToScale(1.0, scaTilt); mdtransrotate = (float)vx / csize.width; mdtrans.rotate(mdtransrotate, csize.width / 2, csize.height / (scaTilt * 2)); mdtrans.scale(1.0, 1.0 / scaTilt); break; } case M_SKET: mouseMoved(e); // simulates a lot of clicking if (sketchdisplay.miTabletMouse.isSelected() && bmoulinactive) LineToCurve(); return; case M_SKET_SNAP: case M_SKET_SNAPPED: mouseMoved(e); return; case M_NONE: mouseMoved(e); return; default: return; } // the dynamic drag type things. currtrans.setTransform(mdtrans); currtrans.concatenate(orgtrans); RedoBackgroundView(); } ///////////////////////////////////////////// public void mouseReleased(MouseEvent e) { mouseDragged(e); // in this mode things happen on release. if ((momotion == M_SKET_SNAP) || (momotion == M_SKET_SNAPPED)) { // start of path if (!bmoulinactive) { if (currpathnode != null) { // splitnode if ((currgenpath != null) && (linesnap_t != -1.0)) SplitCurrpathNode(); ClearSelection(true); StartCurve(currpathnode); repaint(); } } else { // end of path if (currpathnode != null) { if (moulinmleng != 0) currgenpath.IntermedLines(moupath, nmoupathpieces); // handle any tracking of the drawing EndCurve(currpathnode); repaint(); } } } else if ((momotion == M_DYN_DRAG) || (momotion == M_DYN_SCALE) || (momotion == M_DYN_ROT)) { if (momotion == M_DYN_ROT) currtransrotate += mdtransrotate; RedoBackgroundView(); } momotion = M_NONE; repaint(); } ///////////////////////////////////////////// void FrameBackgroundOutline() { System.out.println(" WWWWWW setting FrameBackgroundOutline"); // only to closed loops if (tsketch.opframebackgrounddrag.pnstart != tsketch.opframebackgrounddrag.pnend) return; if (!tsketch.opframebackgrounddrag.plabedl.sketchframedef.IsImageType()) return; OnePath fop = tsketch.opframebackgrounddrag; OnePathNode fopn = fop.pnstart; // check if all paths are non-connective RefPathO srefpathconn = new RefPathO(); int nvpaths = 0; srefpathconn.ccopy(fopn.ropconn); do { OnePath lop = srefpathconn.op; assert lop != null; if (lop == fop) ; else if ((lop.linestyle != SketchLineStyle.SLS_CONNECTIVE) || ((lop.plabedl != null) && (lop.plabedl.barea_pres_signal != SketchLineStyle.ASE_ZSETRELATIVE) && (lop.plabedl.barea_pres_signal != SketchLineStyle.ASE_KEEPAREA))) nvpaths = -1; else if (nvpaths != -1) nvpaths++; } while (!srefpathconn.AdvanceRoundToNode(fopn.ropconn)); List pthstoremove = new ArrayList(); List pthstoadd = new ArrayList(); OnePath gop = fop.plabedl.sketchframedef.MakeBackgroundOutline(1.0, tsketch.sketchLocOffset); gop.CopyPathAttributes(fop); System.out.println("NNNN " + nvpaths + " " + gop.nlines); // bring over any paths connecting to this rectangle where we have moved it if (nvpaths >= 1) FuseNodesS(pthstoremove, pthstoadd, fopn, gop.pnstart, fop, null, sketchdisplay.miShearWarp.isSelected()); pthstoremove.add(fop); pthstoadd.add(gop); CommitPathChanges(pthstoremove, pthstoadd); tsketch.opframebackgrounddrag = gop; sketchdisplay.sketchlinestyle.pthstyleareasigtab.UpdateSFView(gop, true); if (sketchdisplay.bottabbedpane.getSelectedIndex() == 1) sketchdisplay.backgroundpanel.UpdateBackimageCombobox(4); RedrawBackgroundView(); } ///////////////////////////////////////////// Point2D.Float scrddpt = new Point2D.Float(); Point2D.Float ddpt = new Point2D.Float(); OnePath MakeConnectiveLineForData(int cldtype, float sdist) { double x0, y0; double x1, y1; double x2, y2; double x3, y3; assert currgenpath == null; assert (cldtype == 0) || (cldtype == 1) || (cldtype == 2); // 0 is image loop; 1 is survex data; 2 is frame specifier OnePath gop; try { if (cldtype == 0) { scrddpt.setLocation(30, 20); currtrans.inverseTransform(scrddpt, ddpt); x0 = ddpt.getX(); y0 = ddpt.getY(); scrddpt.setLocation(80, 20); currtrans.inverseTransform(scrddpt, ddpt); x1 = ddpt.getX(); y1 = ddpt.getY(); scrddpt.setLocation(80, 40); currtrans.inverseTransform(scrddpt, ddpt); x2 = ddpt.getX(); y2 = ddpt.getY(); scrddpt.setLocation(30, 40); currtrans.inverseTransform(scrddpt, ddpt); x3 = ddpt.getX(); y3 = ddpt.getY(); OnePathNode opns = new OnePathNode((float)x0, (float)y0, GetMidZsel()); opns.SetNodeCloseBefore(tsketch.vnodes, tsketch.vnodes.size()); gop = new OnePath(opns); gop.LineTo((float)x1, (float)y1); gop.LineTo((float)x2, (float)y2); gop.LineTo((float)x3, (float)y3); gop.EndPath(opns); } else if (cldtype == 2) { ddpt.setLocation(csize.width / 3, csize.height / 3); currtrans.inverseTransform(scrddpt, ddpt); OnePathNode opn00 = new OnePathNode((float)ddpt.getX(), (float)ddpt.getY(), GetMidZsel()); OnePathNode opn00t = new OnePathNode((float)(ddpt.getX() + sdist * 0.3), (float)(ddpt.getY() + sdist * 0.2), GetMidZsel()); gop = new OnePath(opn00); gop.EndPath(opn00t); } else { assert cldtype == 1; float sxoffset = 0.0F; for (OnePath op : tsketch.vpaths) { if ((op.linestyle == SketchLineStyle.SLS_CONNECTIVE) && (op.plabedl != null) && op.plabedl.sfontcode.equals("survey")) sxoffset = Math.max(sxoffset, (int)(op.pnstart.pn.getX() / 200 + 1) * 200); } System.out.println(" sXXX " + sxoffset); int nfacets = 12; float rad = sdist; OnePathNode opns = new OnePathNode(sxoffset + rad, 0.0F, GetMidZsel()); opns.SetNodeCloseBefore(tsketch.vnodes, tsketch.vnodes.size()); gop = new OnePath(opns); for (int i = 1; i <= nfacets; i++) { double ang = i * Math.PI * 3 / 2 / nfacets; gop.LineTo(sxoffset + (float)Math.cos(ang) * rad, -(float)Math.sin(ang) * rad); } for (int i = 1; i < nfacets; i++) { double ang = i * Math.PI * 3 / 2 / nfacets; gop.LineTo(sxoffset + (float)Math.sin(ang) * rad, 2 * rad - (float)Math.cos(ang) * rad); } OnePathNode opne = new OnePathNode(sxoffset - rad, rad * 2, GetMidZsel()); gop.EndPath(opne); } } catch (NoninvertibleTransformException ex) { TN.emitError("Bad transform"); return null; } gop.linestyle = SketchLineStyle.SLS_CONNECTIVE; gop.bWantSplined = false; gop.plabedl = new PathLabelDecode(); if ((cldtype == 0) || (cldtype == 2)) { gop.plabedl.barea_pres_signal = SketchLineStyle.ASE_SKETCHFRAME; // just now need to find where it is in the list in the combo-box gop.plabedl.iarea_pres_signal = SketchLineStyle.iareasigframe; gop.plabedl.sketchframedef = new SketchFrameDef(); } else gop.plabedl.sfontcode = "survey"; return gop; } ///////////////////////////////////////////// boolean MoveGround(boolean bBackgroundOnly) { // prob originally worked from currgenpath, but then generalized to more odd ways of selecting Set opselset = MakeTotalSelList(); if ((opselset.size() != 1) || bmoulinactive) return TN.emitWarning("must have one path selected"); OnePath op = opselset.iterator().next(); float[] pco = op.GetCoords(); if (op.linestyle == SketchLineStyle.SLS_CENTRELINE) { if ((tsketch.opframebackgrounddrag == null) || !tsketch.opframebackgrounddrag.IsSketchFrameConnective()) return TN.emitWarning("no background frame image to drag"); SketchFrameDef sketchframedef = tsketch.opframebackgrounddrag.plabedl.sketchframedef; if (sketchframedef.IsImageType() || (sketchframedef.pframesketch == null) || !bBackgroundOnly || (op.nlines != 1)) return TN.emitWarning("must have non-centreline path selected (unless positioning plan sketch in elevation)"); // may want to outsource this to MatchSketchCentrelines class // final parameter would allow taking a subset value that would subselect centrelines and connective lines (whose ends connect between stations) that have been subsetted // The import for the elevation centreline would require a designated subset to define this, // which could be specified by the include of the plan used for shifting to position along the centrelines // possible to a series of subsets, specifying which ones to fold left or right // in which case, this set would need to go as the final parameter here OnePath opcorresp = MatchSketchCentrelines.FindBestStationpairMatch(sketchframedef.pframesketch.vpaths, op.pnstart.pnstationlabel, op.pnend.pnstationlabel, null); if (opcorresp == null) return TN.emitWarning("no corresponding centreline found for this elevation leg"); sketchframedef.ConvertSketchTransformTCLINE(pco, tsketch.realposterpaperscale, tsketch.sketchLocOffset, currtrans, opcorresp); sketchdisplay.sketchlinestyle.pthstyleareasigtab.UpdateSFView(tsketch.opframebackgrounddrag, true); RedoBackgroundView(); return true; } // implementation on the screen if (op.nlines == 1) mdtrans.setToTranslation(pco[2] - pco[0], pco[3] - pco[1]); else if (op.nlines == 2) { float x2 = pco[4] - pco[0]; float y2 = pco[5] - pco[1]; float x1 = pco[2] - pco[0]; float y1 = pco[3] - pco[1]; double len2 = Math.sqrt(x2 * x2 + y2 * y2); double len1 = Math.sqrt(x1 * x1 + y1 * y1); double len12 = len1 * len2; if (len12 == 0.0F) return false; double dot12 = (x1 * x2 + y1 * y2) / len12; double dot1p2 = (x1 * y2 - y1 * x2) / len12; double sca = len2 / len1; mdtrans.setToTranslation(pco[0], pco[1]); mdtrans.scale(sca, sca); orgtrans.setTransform(dot12, dot1p2, -dot1p2, dot12, 0.0F, 0.0F); mdtrans.concatenate(orgtrans); mdtrans.translate(-pco[0], -pco[1]); } else return TN.emitWarning("must have a two or three point path selected"); // implementation in the settings for the background if (!bBackgroundOnly) { currtrans.concatenate(mdtrans); DeleteSel(); return true; } // we apply the transform to the matrix *and* to the underlying positioning values (in ConvertSketchTransformT) // to check the values come out the same, because it was a hard computation to get right. backgroundimg.PreConcatBusiness(mdtrans); if ((tsketch.opframebackgrounddrag == null) || !tsketch.opframebackgrounddrag.IsSketchFrameConnective()) return TN.emitWarning("no background frame image to drag"); SketchFrameDef sketchframedef = tsketch.opframebackgrounddrag.plabedl.sketchframedef; System.out.println("nilllll " + sketchframedef.pframesketchtrans); AffineTransform lpframetrans = new AffineTransform(sketchframedef.pframesketchtrans); if (!sketchframedef.sfelevvertplane.equals("") && (scaTilt == 1.0)) return TN.emitWarning("cannot shift vertical image when view not tilted"); sketchframedef.ConvertSketchTransformT(pco, op.nlines, tsketch.realposterpaperscale, tsketch.sketchLocOffset, currtrans, tsketch.opframebackgrounddrag); sketchdisplay.sketchlinestyle.pthstyleareasigtab.UpdateSFView(tsketch.opframebackgrounddrag, true); DeleteSel(); FrameBackgroundOutline(); RedoBackgroundView(); return true; } } tunnelx-20140102.orig/src/ConnectiveCentrelineTabPane.java0000644000000000000000000000420211762432750020267 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2004 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import javax.swing.JComboBox; import javax.swing.JPanel; import javax.swing.JButton; import javax.swing.BoxLayout; import javax.swing.JCheckBox; import javax.swing.JToggleButton; import javax.swing.JTextField; import javax.swing.JTextArea; import javax.swing.JLabel; import java.awt.GridLayout; import java.awt.BorderLayout; import java.awt.FlowLayout; ///////////////////////////////////////////// class ConnectiveCentrelineTabPane extends JPanel { JTextField tfhead = new JTextField("junk1"); JTextField tftail = new JTextField("junk2"); JTextField tfelev = new JTextField("junk3"); ///////////////////////////////////////////// ConnectiveCentrelineTabPane() { super(new BorderLayout()); tfhead.setEditable(false); tftail.setEditable(false); tfelev.setEditable(false); JPanel pfie = new JPanel(new GridLayout(3, 2)); pfie.add(new JLabel("tail:")); pfie.add(tftail); pfie.add(new JLabel("head:")); pfie.add(tfhead); pfie.add(new JLabel("elev:")); pfie.add(tfelev); JPanel pptop = new JPanel(new BorderLayout()); pptop.add(new JLabel("Centreline leg", JLabel.CENTER), BorderLayout.NORTH); pptop.add(pfie, BorderLayout.CENTER); add(pptop, BorderLayout.NORTH); } } tunnelx-20140102.orig/src/SketchSecondRenderPanel.java0000644000000000000000000002317612261213471017426 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2009 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import javax.swing.JPanel; import javax.swing.JButton; import javax.swing.JRadioButton; import javax.swing.ButtonGroup; import javax.swing.JTextField; import javax.swing.JTextArea; import javax.swing.JLabel; import javax.swing.JCheckBox; import javax.swing.JScrollPane; import javax.swing.JComboBox; import javax.swing.event.DocumentListener; import javax.swing.event.DocumentEvent; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.Insets; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseListener; import java.awt.event.MouseEvent; import java.io.IOException; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.geom.AffineTransform; import java.awt.geom.NoninvertibleTransformException; import java.awt.Graphics2D; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.awt.image.WritableRaster; import java.awt.image.DataBuffer; import java.awt.Image; import java.awt.RenderingHints; import java.awt.AlphaComposite; import java.awt.Composite; import java.awt.Rectangle; import java.awt.Color; import javax.imageio.ImageIO; import java.util.List; import java.util.ArrayList; ///////////////////////////////////////////// class SketchSecondRenderPanel extends JPanel implements MouseListener //, MouseMotionListener, MouseWheelListener { Image mainImg = null; Graphics2D g2dimage = null; GraphicsAbstraction gaimage = null; Dimension csize = new Dimension(0, 0); boolean bredrawbackground = false; SketchSecondRender sketchsecondrender; SketchDisplay sketchdisplay; AffineTransform lrendtrans = new AffineTransform(); AffineTransform rendtrans = new AffineTransform(); // transform used in the main window AffineTransform crendtrans = new AffineTransform(); // transform displaced to match the middle of the main window AffineTransform satrans = new AffineTransform(); ///////////////////////////////////////////// public void paintComponent(Graphics g) { // test if resize has happened because we are rebuffering things if ((mainImg == null) || (getSize().height != csize.height) || (getSize().width != csize.width)) { csize.width = getSize().width; csize.height = getSize().height; mainImg = createImage(csize.width, csize.height); g2dimage = (Graphics2D)mainImg.getGraphics(); gaimage = new GraphicsAbstraction(g2dimage); bredrawbackground = true; satrans.setTransform(g2dimage.getTransform()); SetCrendtrans(); } if (bredrawbackground) { System.out.println("redrawing22222back"); OneSketch tsketch = sketchdisplay.sketchgraphicspanel.tsketch; // simply redraw the back image into the front, transformed for fast dynamic rendering. g2dimage.setColor(SketchLineStyle.blankbackimagecol); g2dimage.fillRect(0, 0, csize.width, csize.height); // the frame image types -- which will replace the old style OnePath fop = tsketch.opframebackgrounddrag; if ((fop != null) && (fop.plabedl != null) && (fop.plabedl.sketchframedef != null) && ((fop.plabedl.sketchframedef.pframeimage != null) || (fop.plabedl.sketchframedef.pframesketch != null))) { SketchFrameDef sketchframedef = fop.plabedl.sketchframedef; gaimage.transform(crendtrans); gaimage.transform(sketchframedef.pframesketchtrans); if (sketchframedef.pframeimage != null) gaimage.drawImage(sketchframedef.pframeimage.GetImage(true)); else sketchframedef.pframesketch.paintWqualitySketch(gaimage, Math.max(2, sketchdisplay.printingpanel.cbRenderingQuality.getSelectedIndex()), null); //backimagedoneGraphics.setTransform(ucurrtrans); //ga.drawPath(sketchgraphicspanel.tsketch.opframebackgrounddrag, SketchLineStyle.framebackgrounddragstyleattr); g2dimage.setTransform(satrans); } gaimage.transform(crendtrans); g2dimage.setFont(sketchdisplay.sketchlinestyle.defaultfontlab); boolean bHideMarkers = !sketchdisplay.miShowNodes.isSelected(); int stationnamecond = (sketchdisplay.miStationNames.isSelected() ? 1 : 0) + (sketchdisplay.miStationAlts.isSelected() ? 2 : 0); tsketch.paintWbkgd(gaimage, !sketchdisplay.miCentreline.isSelected(), bHideMarkers, stationnamecond, false, tsketch.vpaths, null, tsketch.vsareas, tsketch.vnodes, false); g2dimage.setTransform(satrans); bredrawbackground = false; } Graphics2D g2d = (Graphics2D)g; g.drawImage(mainImg, 0, 0, null); // draw the elevation arrow onto here if (sketchdisplay.selectedsubsetstruct.elevset.bIsElevStruct) { GraphicsAbstraction ga = new GraphicsAbstraction(g2d); ga.transform(crendtrans); ga.drawShape(sketchdisplay.sketchgraphicspanel.elevarrow, SketchLineStyle.ActiveLineStyleAttrs[SketchLineStyle.SLS_DETAIL]); } } ///////////////////////////////////////////// // the window view is clipped (translated) to the centre of the panel void SwapCopyView(boolean bswap) { if (bswap) { crendtrans.setTransform(rendtrans); rendtrans.setTransform(sketchdisplay.sketchgraphicspanel.currtrans); sketchdisplay.sketchgraphicspanel.currtrans.setTransform(crendtrans); sketchdisplay.sketchgraphicspanel.RedoBackgroundView(); } else rendtrans.setTransform(sketchdisplay.sketchgraphicspanel.currtrans); SetCrendtrans(); } ///////////////////////////////////////////// void SetCrendtrans() { // will translate by the centreof the mini screen. doesn't really work for moving that mid panel side to side // because the main panel also changes, but does work for the up and down split panel. crendtrans.setToTranslation((getSize().width - sketchdisplay.sketchgraphicspanel.csize.width) / 2, (getSize().height - sketchdisplay.sketchgraphicspanel.csize.height) / 2); crendtrans.concatenate(rendtrans); bredrawbackground = true; repaint(); } ///////////////////////////////////////////// // this should move the panel -- the click to the centre public void mouseClicked(MouseEvent e) { int xv = getSize().width / 2 - e.getX(); int yv = getSize().height / 2 - e.getY(); lrendtrans.setTransform(rendtrans); // will translate by the centreof the rendtrans.setToTranslation(xv, yv); rendtrans.concatenate(lrendtrans); SetCrendtrans(); } public void mouseEntered(MouseEvent e) {;}; public void mouseExited(MouseEvent e) {;}; public void mouseReleased(MouseEvent e) {;} public void mousePressed(MouseEvent e) {;} ///////////////////////////////////////////// SketchSecondRenderPanel(SketchSecondRender lsketchsecondrender) { super(false); // not doublebuffered (we do it ourselves) sketchsecondrender = lsketchsecondrender; sketchdisplay = sketchsecondrender.sketchdisplay; addMouseListener(this); } } ///////////////////////////////////////////// class SketchSecondRender extends JPanel { SketchDisplay sketchdisplay; JButton buttswapview = new JButton("Swap"); JButton buttcopyview = new JButton("Copy"); SketchSecondRenderPanel sketchsecondrenderpanel = null; ///////////////////////////////////////////// SketchSecondRender(SketchDisplay lsketchdisplay) { sketchdisplay = lsketchdisplay; sketchsecondrenderpanel = new SketchSecondRenderPanel(this); setLayout(new BorderLayout()); JPanel pan1 = new JPanel(new GridLayout(0, 2)); pan1.add(buttswapview); pan1.add(buttcopyview); buttswapview.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { sketchsecondrenderpanel.SwapCopyView(true); } }); buttcopyview.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { sketchsecondrenderpanel.SwapCopyView(false); } }); add(sketchsecondrenderpanel, BorderLayout.CENTER); add(pan1, BorderLayout.SOUTH); } ///////////////////////////////////////////// void Update(boolean btabbingchanged) { if (btabbingchanged) { System.out.println("UpdateSecondRender"); sketchsecondrenderpanel.bredrawbackground = true; repaint(); } } } tunnelx-20140102.orig/src/TN.java0000644000000000000000000002075712261213471013254 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.Color; import java.awt.image.BufferedImage; import java.awt.BasicStroke; import java.awt.Font; import java.awt.GraphicsEnvironment; import java.util.Random; import java.util.Calendar; import java.text.SimpleDateFormat; import javax.swing.JTextArea; import java.util.Set; import java.util.HashSet; // // // TN // // class TN { // the file dialog box // relative paths don't work when we use them in the SvxFileDialog dialog box -- it makes it relative to the My Documents directory static FileAbstraction currentDirectory = null; // set in the main() function static FileAbstraction currentDirectoryIMG = null; // set in the main() function static FileAbstraction currprintdir = null; static String survexexecutabledir = ""; // a string we can add "cavern.exe" to static String inkscapeexecutabledir = ""; // a string we can add "inkscape.com" to //static String troggleurl = "http://framos.lawoftheland.co.uk/troggle/" static String troggleurl = "http://127.0.0.1:8000/"; // jgtuploadfile, jgtfile static String tunnelversion = "version2012-08-01 Austria"; static String tunneluser = "austria12"; //"nielcaver"; // reset in InitFA from system properties static String tunnelpassword = "gosser"; // to be set from the command line static String tunnelproject = "cuccaustria"; // to be set from the command line static String tunneldate() { return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Calendar.getInstance().getTime()); } // convert degrees to radians static double degsin(double ang) { return (ang == 90 ? 1.0 : (ang == -90 ? -1.0 : Math.sin(Math.toRadians(ang)))); } static double degcos(double ang) { return (ang == 90 ? 0.0 : (ang == -90 ? -0.0 : Math.cos(Math.toRadians(ang)))); } static double percentdeg(double percent) { return Math.toDegrees(Math.atan(percent / 100)); }; static float radiusofsurveylabel_S = 50.0F; // standard measurements static int STATION_FIELD_WIDTH = 20; static int XSECTION_MAX_NSIDES = 50; static float CENTRELINE_MAGNIFICATION = 10.0F; // factor to increase the centreline pos by so that we have less problem with the text rendering. // printing scale static int prtscale = 500; // could be a menu option static String framestylesubset = "framestyle"; static float defaultrealposterpaperscale = 1000.0F; // scaledown when we import background sketches into areas on the poster size (so posters don't have to be many kms wide in real space, and instead at least approx on right scale) static String planCLINEsubset = "plan_TOP"; static String elevCLINEsubset = "elevation_TOP"; static String flipCLINEsignal = "flip_TOP"; //static String XSectionDefaultPoly = "4 1 1 0 0 1 0 -1 0 1 -1 0 0 1 0 1 0"; static String XSectionDefaultVec = "0 0 0"; static int XSinteractiveSensitivitySQ = 400; static String nl = "\r\n"; public static boolean IsWhiteSpace(char ch) { return((ch == ' ') || (ch == '\t')); } // wireframe graphics static Color wfmtubeActive = Color.magenta; static Color wfmtubeInactive = new Color(0, 0, 150); // Color.blue; static Color wfmtubeDel = Color.red; static Color wfmxsectionActive = Color.magenta; static Color wfmxsectionInactive = Color.blue; static Color wfmpointActive = Color.magenta; static Color wfmpointInactive = Color.green; static Color wfmnameActive = Color.magenta; static Color wfmnameInactive = Color.cyan; static Color wfmBackground = new Color(100, 100, 100); //Color.black; static Color wfdaxesXY = Color.cyan; static Color wfdaxesZ = Color.blue; static Color wfmLeg = Color.white; // xsection graphics static Color xsgLines = Color.black; static Color xsgSelected = Color.green; static Color xsgOrigin = Color.yellow; static Color xsgGridline = Color.blue; static Color xsgCornerNode = Color.red; static int xsgOriginSize = 5; static int xsgPointSize = 3; static Color skeBackground = new Color(200, 200, 200); static char PathDelimeterChar = '|'; static String PathDelimeter = "|"; static char StationDelimeterChar = '^'; static String StationDelimeter = "^"; static String ExportDelimeter = "."; static String SurvexExtension = ".svx"; static String ESurvexExtension = ".evx"; static String TunnelExtension = ".tun"; // sizes of the preview sections static int XprevWidth = 20; static int XprevHeight = 30; static int XprevBorder = 3; static int XprevItemsAcross = 6; static int XprevGap = 3; static Random ran = new Random(); static LegLineFormat defaultleglineformat = new LegLineFormat(); ///////////////////////////////////////////// ///////////////////////////////////////////// ///////////////////////////////////////////// // file names static String setSuffix(String fname, String suffix) { int il = fname.lastIndexOf('.'); return (il == -1 ? fname : fname.substring(0, il)) + suffix; } ///////////////////////////////////////////// static String getSuffix(String fname) { int il = fname.lastIndexOf('.'); return (il == -1 ? "" : fname.substring(il)); } ///////////////////////////////////////////// static String loseSuffix(String fname) { int il = fname.lastIndexOf('.'); return (il == -1 ? fname : fname.substring(0, il)); } ///////////////////////////////////////////// static String shortenString(String ssval, int maxleng) { if (ssval.length() < maxleng) return ssval; int is = ssval.indexOf("/"); int il = ssval.lastIndexOf("/"); if ((is != il) && (is != -1)) { String lssval = ssval.substring(0, is + 1) + "..." + ssval.substring(il); if (lssval.length() < maxleng) return lssval; } int ntrail = maxleng / 2 + 1; int nhead = maxleng - ntrail - 3; return ssval.substring(0, nhead) + "..." + ssval.substring(ssval.length() - ntrail); } ///////////////////////////////////////////// static String SUFF_XML = ".xml"; static String SUFF_HTML = ".html"; static String SUFF_SVX = ".svx"; static String SUFF_POS = ".pos"; static String SUFF_SRV = ".srv"; // walls subfile extension static String SUFF_TOP = ".top"; static String SUFF_WALLS = ".prj"; static String SUFF_VRML = ".wrl"; static String SUFF_PNG = ".png"; static String SUFF_JPG = ".jpg"; static String SUFF_3D = ".3d"; static String SUFF_PDF = ".pdf"; static String SUFF_SVG = ".svg"; static String SUFF_TXT = ".TXT"; static String SUFF_GIF = ".GIF"; static String[] SUFF_IGNORE = { "", ".extra", ".old", ".status", ".lev", ".pl", ".py", ".Log", ".DS_Store"}; // (TortoiseCVS generates a lot of files called "TortoiseCVS.Status") // constants used in the userinterface windows static Color sketchlinestyle_col = new Color(0.5F, 0.3F, 0.8F); static boolean bVerbose = true; static boolean bTodeNode = false; static MainBox mainbox = null; static Set pastmessages = new HashSet(); // message making public static void emitMessage(String mess) { if (bVerbose) System.out.println(mess); } public static boolean emitWarning(String mess) { System.out.println("Warning: " + mess); boolean btofront = !pastmessages.contains(mess); if (btofront) pastmessages.add(mess); mainbox.emitErrorMessageLine("\nWarning: " + mess, btofront); return true; } public static void emitError(String mess) { System.out.println("ERROR: " + mess); mainbox.emitErrorMessageLine("\nERROR: " + mess, true); throw new RuntimeException("error"); } // not sure this one makes a lot of sense. should be be asserts? public static void emitProgError(String mess) { System.out.println("Programming Error: " + mess); mainbox.emitErrorMessageLine("\nERROR: " + mess, true); } } tunnelx-20140102.orig/src/LineStyleAttr.java0000644000000000000000000001152211762432750015474 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2007 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.BasicStroke; import java.awt.Font; import java.awt.Color; ///////////////////////////////////////////// class LineStyleAttr { static int Nlinestyles = 9; // takes in SLS_FILLED int linestyle; private String sstrokewidth; private String sspikegap; private String sgapleng; private String sspikeheight; private String sstrokecolour; Color strokecolour; float strokewidth; float spikegap; float gapleng; float spikeheight; BasicStroke linestroke = null; ///////////////////////////////////////////// LineStyleAttr(LineStyleAttr lls) { linestyle = lls.linestyle; sstrokewidth = lls.sstrokewidth; sspikegap = lls.sspikegap; sgapleng = lls.sgapleng; sspikeheight = lls.sspikeheight; sstrokecolour = lls.sstrokecolour; //System.out.println("sg3 " + sspikegap + " ls " + linestyle); } ///////////////////////////////////////////// LineStyleAttr(int llinestyle, String lsstrokewidth, String lsspikegap, String lsgapleng, String lsspikeheight, String lsstrokecolour) { linestyle = llinestyle; sstrokewidth = lsstrokewidth; sspikegap = lsspikegap; sgapleng = lsgapleng; sspikeheight = lsspikeheight; sstrokecolour = lsstrokecolour; //System.out.println("sg2 " + sspikegap + " ls " + linestyle); } ///////////////////////////////////////////// LineStyleAttr(int llinestyle, float lstrokewidth, float lspikegap, float lgapleng, float lspikeheight, Color lstrokecolour) { //assert lstrokecolour != null; linestyle = llinestyle; strokewidth = lstrokewidth; spikegap = lspikegap; gapleng = lgapleng; spikeheight = lspikeheight; strokecolour = lstrokecolour; SetUpBasicStroke(); } ///////////////////////////////////////////// void Construct(SubsetAttr lsubsetattr, Color defaultcolor) { strokewidth = SubsetAttr.ConvertFloat(lsubsetattr.EvalVars(sstrokewidth), (linestyle != SketchLineStyle.SLS_FILLED ? 2.0F : 0.0F)); spikegap = SubsetAttr.ConvertFloat(lsubsetattr.EvalVars(sspikegap), 0.0F); gapleng = SubsetAttr.ConvertFloat(lsubsetattr.EvalVars(sgapleng), 0.0F); spikeheight = SubsetAttr.ConvertFloat(lsubsetattr.EvalVars(sspikeheight), 0.0F); gapleng = SubsetAttr.ConvertFloat(lsubsetattr.EvalVars(sgapleng), 0.0F); strokecolour = SubsetAttr.ConvertColour(lsubsetattr.EvalVars(sstrokecolour), defaultcolor); SetUpBasicStroke(); } ///////////////////////////////////////////// void SetUpBasicStroke() { if (linestyle == SketchLineStyle.SLS_FILLED) { if (strokewidth != 0.0F) TN.emitWarning("nonzero strokewidth " + strokewidth + " on filled line"); } else { if (strokewidth == 0.0F && strokecolour != null) TN.emitWarning("zero strokewidth on line style; use colour=null; colour was " + strokecolour.toString()); } if (spikeheight != 0.0F) { if ((linestyle != SketchLineStyle.SLS_PITCHBOUND) && (linestyle != SketchLineStyle.SLS_CEILINGBOUND)) TN.emitWarning("spikes only on pitch and ceiling bounds please"); } // setup the basicstroke if (strokewidth != 0.0F) { // dotted float mitrelimit = strokewidth * 5.0F; if ((gapleng != 0.0F) && (spikeheight == 0.0F)) { float[] dash = new float[2]; dash[0] = spikegap - gapleng; if (dash[0] < 0) TN.emitError("Dash phase (spikegap - gaplength) is negative)"); dash[1] = gapleng; linestroke = new BasicStroke(strokewidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, mitrelimit, dash, dash[0] / 2); } else linestroke = new BasicStroke(strokewidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, mitrelimit); } } ///////////////////////////////////////////// LineStyleAttr(int llinestyle) { linestyle = llinestyle; } ///////////////////////////////////////////// float GetStrokeWidth() { return strokewidth; } ///////////////////////////////////////////// void SetColor(Color lcolour)//Used when you want to override the color, eg when colouring by altitude { strokecolour = lcolour; } } tunnelx-20140102.orig/src/WarpPiece.java0000644000000000000000000001402011762432750014604 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2009 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.util.List; import java.awt.geom.Point2D; import java.awt.geom.GeneralPath; // class used for warping a path when FuseNodes is used, either in plan or elevation case ///////////////////////////////////////////// class WarpPiece { static final int WARP_NORMALWARP = 0; static final int WARP_SHEARWARP = 1; static final int WARP_ZWARP = 2; int iwarp; // the line from and line to OnePathNode pnstart; OnePathNode pnend; OnePathNode npnstart; OnePathNode npnend; // initial vector double xv; double yv; double vsq; // final vector double nxv; double nyv; double nvsq; // translation vector for shear warp double xt = 0.0; double yt = 0.0; ///////////////////////////////////////////// void SetUpVectors() { // initial vector xv = pnend.pn.getX() - pnstart.pn.getX(); yv = pnend.pn.getY() - pnstart.pn.getY(); vsq = xv * xv + yv * yv; // final vector nxv = npnend.pn.getX() - npnstart.pn.getX(); nyv = npnend.pn.getY() - npnstart.pn.getY(); nvsq = nxv * nxv + nyv * nyv; } ///////////////////////////////////////////// // construct from one end path drag (bug could do total move) WarpPiece(OnePathNode pnfrom, OnePathNode pnto, OnePath axop, int liwarp) { iwarp = liwarp; pnstart = axop.pnstart; pnend = axop.pnend; npnstart = (axop.pnstart == pnfrom ? pnto : axop.pnstart); npnend = (axop.pnend == pnfrom ? pnto : axop.pnend); xt = pnto.pn.getX() - pnfrom.pn.getX(); yt = pnto.pn.getY() - pnfrom.pn.getY(); SetUpVectors(); } ///////////////////////////////////////////// WarpPiece(OnePathNode lpnstart, OnePathNode lpnend, OnePathNode lnpnstart, OnePathNode lnpnend) { iwarp = WARP_ZWARP; pnstart = lpnstart; pnend = lpnend; npnstart = lnpnstart; npnend = lnpnend; SetUpVectors(); } ///////////////////////////////////////////// void WarpPoint(Point2D res, double x, double y) { // translation case (if endpoints match). if ((vsq == 0.0) || (nvsq == 0.0)) { if ((vsq != 0.0) || (nvsq != 0.0)) TN.emitWarning("Bad warp: only one axis vector is zero length"); res.setLocation(x + xt, y + yt); } // by shearing else if (iwarp == WARP_SHEARWARP) { double vix = x - pnstart.pn.getX(); double viy = y - pnstart.pn.getY(); double lam = (vix * xv + viy * yv) / vsq; res.setLocation(x + lam * xt, y + lam * yt); } else if (iwarp == WARP_ZWARP) { if ((xv == 0.0) || (nxv == 0.0)) TN.emitWarning("zwarp on zero x axis"); double vix = x - pnstart.pn.getX(); double viy = y - pnstart.pn.getY(); double lam = (xv != 0.0 ? vix / xv : (vix * xv + viy * yv) / vsq); // goes to other warp when zero //float ay = (float)pnstart.pn.getY() + lam * yv; double dy = viy - lam * yv; res.setLocation(npnstart.pn.getX() + lam * nxv, npnstart.pn.getY() + lam * nyv + dy); } // rotation case (one endpoint matches) else { assert (iwarp == WARP_NORMALWARP); double vix = x - pnstart.pn.getX(); double viy = y - pnstart.pn.getY(); double lam = (vix * xv + viy * yv) / vsq; double plam = (vix * (-yv) + viy * (xv)) / vsq; res.setLocation(npnstart.pn.getX() + lam * nxv + plam * (-nyv), npnstart.pn.getY() + lam * nyv + plam * (nxv)); } } ///////////////////////////////////////////// OnePath WarpPathS(OnePath op) { assert pnstart == op.pnstart; assert pnend == op.pnend; float[] pco = op.GetCoords(); OnePath res = new OnePath(npnstart); Point2D pt = new Point2D.Float(); for (int i = 1; i < op.nlines; i++) { WarpPoint(pt, pco[i * 2], pco[i * 2 + 1]); res.LineTo((float)pt.getX(), (float)pt.getY()); } res.EndPath(npnend); res.CopyPathAttributes(op); return res; } ///////////////////////////////////////////// OnePathNode WarpElevationNode(OnePathNode opn, List nopelevarr, List opelevarr, Point2D ptspare) { System.out.println("node " + opn.pn.getX() + "," + opn.pn.getY()); if (opn == pnstart) return npnstart; if (opn == pnend) return npnend; for (int i = 0; i < nopelevarr.size(); i++) { if (opn == opelevarr.get(i).pnstart) return nopelevarr.get(i).pnstart; if (opn == opelevarr.get(i).pnend) return nopelevarr.get(i).pnend; } WarpPoint(ptspare, opn.pn.getX(), opn.pn.getY()); System.out.println(" tonode " + ptspare.getX() + "," + ptspare.getY()); return new OnePathNode((float)ptspare.getX(), (float)ptspare.getY(), 0.0F); } ///////////////////////////////////////////// void WarpElevationBatch(List res, List opelevarr) { Point2D ptspare = new Point2D.Float(); assert res.isEmpty(); for (int j = 0; j < opelevarr.size(); j++) { OnePath op = opelevarr.get(j); float[] pco = op.GetCoords(); System.out.println("web " + j + " " + op.nlines + " x " + pco[0]); OnePath nop = new OnePath(WarpElevationNode(op.pnstart, res, opelevarr, ptspare)); for (int i = 1; i < op.nlines; i++) { WarpPoint(ptspare, pco[i * 2], pco[i * 2 + 1]); nop.LineTo((float)ptspare.getX(), (float)ptspare.getY()); } nop.EndPath(WarpElevationNode(op.pnend, res, opelevarr, ptspare)); nop.CopyPathAttributes(op); res.add(nop); } } }; tunnelx-20140102.orig/src/SketchPrintPanel.java0000644000000000000000000005714412261213471016151 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2004 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import javax.swing.JPanel; import javax.swing.JButton; import javax.swing.JRadioButton; import javax.swing.ButtonGroup; import javax.swing.JTextField; import javax.swing.JTextArea; import javax.swing.JLabel; import javax.swing.JCheckBox; import javax.swing.JScrollPane; import javax.swing.JComboBox; import javax.swing.event.DocumentListener; import javax.swing.event.DocumentEvent; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.Insets; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.geom.AffineTransform; import java.awt.geom.NoninvertibleTransformException; import java.awt.Graphics2D; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.awt.image.WritableRaster; import java.awt.image.DataBuffer; import java.awt.Image; import java.awt.RenderingHints; import java.awt.AlphaComposite; import java.awt.Composite; import java.awt.Rectangle; import java.awt.Color; import javax.imageio.ImageIO; import java.util.List; import java.util.ArrayList; ///////////////////////////////////////////// class SketchPrintPanel extends JPanel { SketchDisplay sketchdisplay; double truewidth; double trueheight; double realpaperscale; Rectangle2D printrect; // one of these two is used for the printrect Rectangle2D subsetrect = null; Rectangle2D windowrectreal = null; double dpmetre; int pixelheight; int pixelwidth; int lastpixfield = 0; JTextField tftruesize = new JTextField(); JTextField dpifield = new JTextField("200"); JTextField tfpixelswidth = new JTextField(); JTextField tfpixelsheight = new JTextField(); JTextField tfdefaultdirname = new JTextField(); JTextField tfdefaultsavename = new JTextField(); JCheckBox chGrayScale = new JCheckBox("Gray Scale"); JComboBox cbBitmaptype = new JComboBox(); JCheckBox chAntialiasing = new JCheckBox("Antialiasing", true); JCheckBox chTransparentBackground = new JCheckBox("Transparent", false); JComboBox cbRenderingQuality = new JComboBox(); JButton buttatlas = new JButton("Atlas"); JButton buttpng = new JButton("PNG"); JButton buttjpg = new JButton("JPG"); JButton buttsvg = new JButton("SVG"); JButton buttsvgnew = new JButton("SVGnew"); JButton buttnet = new JButton("NET"); JButton buttoverlay = new JButton("OVERLAY"); JButton buttresetdir = new JButton("ResetDIR"); AffineTransform aff = new AffineTransform(); ///////////////////////////////////////////// SketchPrintPanel(SketchDisplay lsketchdisplay) { sketchdisplay = lsketchdisplay; setLayout(new BorderLayout()); JPanel pan1 = new JPanel(new GridLayout(4, 2)); tftruesize.setEditable(false); tfdefaultdirname.setEditable(false); pan1.add(new JLabel("Real dimensions:", JLabel.RIGHT)); pan1.add(tftruesize); pan1.add(new JLabel("dots/inch (1:1000):", JLabel.RIGHT)); pan1.add(dpifield); dpifield.addActionListener(new pixfieldlisten(0)); //dpifield.getDocument().addDocumentListener(new pixfieldlisten(0)); tfpixelswidth.addActionListener(new pixfieldlisten(1)); tfpixelsheight.addActionListener(new pixfieldlisten(2)); pan1.add(new JLabel("Pixel dimensions:", JLabel.RIGHT)); JPanel pan4 = new JPanel(new GridLayout(1, 2)); pan4.add(tfpixelswidth); pan4.add(tfpixelsheight); pan1.add(pan4); pan1.add(tfdefaultdirname); pan1.add(tfdefaultsavename); add(pan1, BorderLayout.NORTH); JPanel pan2 = new JPanel(new GridLayout(1, 2)); JPanel panchb = new JPanel(new GridLayout(0, 1)); JPanel panbutts = new JPanel(new GridLayout(0, 1)); buttatlas.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { AutoOutputPNG(); } }); buttpng.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { OutputIMG("png", cbRenderingQuality.getSelectedIndex(), false); } }); buttsvg.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { OutputIMG("svg", cbRenderingQuality.getSelectedIndex(), false); } }); buttsvgnew.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { OutputIMG("svgnew", cbRenderingQuality.getSelectedIndex(), false); } }); buttnet.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { UploadPNG(false); } }); buttoverlay.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { UploadPNG(true); } }); buttresetdir.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ResetDIR(true); } }); panbutts.add(buttpng); //panbutts.add(buttjpg); panbutts.add(buttsvg); panbutts.add(buttsvgnew); panbutts.add(buttnet); panbutts.add(buttoverlay); panbutts.add(buttresetdir); //panbutts.add(buttatlas); pan2.add(panbutts); cbBitmaptype.addItem("RGB colours"); cbBitmaptype.addItem("Grey scale"); cbBitmaptype.addItem("Two tone"); panchb.add(cbBitmaptype); panchb.add(chAntialiasing); panchb.add(chTransparentBackground); cbRenderingQuality.addItem("Quick draw"); cbRenderingQuality.addItem("Show images"); cbRenderingQuality.addItem("Update styles"); cbRenderingQuality.addItem("Full draw"); panchb.add(cbRenderingQuality); pan2.add(panchb); add(pan2, BorderLayout.CENTER); } ///////////////////////////////////////////// void ResetDIR(boolean bresetfromcurrent) { if (bresetfromcurrent) TN.currprintdir = FileAbstraction.MakeCanonical(TN.currentDirectory); // alternatively could use FileAbstraction MakeCurrentUserDirectory() tfdefaultdirname.setText(TN.currprintdir.getAbsolutePath()); String bname = sketchdisplay.selectedsubsetstruct.GetFirstSubset(); if (bname == null) bname = TN.loseSuffix(sketchdisplay.sketchgraphicspanel.tsketch.sketchfile.getName()); tfdefaultsavename.setText(bname); System.out.println("resetting printdir " + bname + " " + bresetfromcurrent); } ///////////////////////////////////////////// void UpdatePrintingRectangle(Vec3 sketchLocOffset, double lrealposterpaperscale, boolean bupdatewindowrect) { if (bupdatewindowrect) { try { sketchdisplay.printingpanel.windowrectreal = sketchdisplay.sketchgraphicspanel.currtrans.createInverse().createTransformedShape(sketchdisplay.sketchgraphicspanel.windowrect).getBounds(); } catch (NoninvertibleTransformException ex) {;} //System.out.println("made new windowrectreal " + sketchdisplay.printingpanel.windowrectreal.toString()); } printrect = (sketchdisplay.selectedsubsetstruct.vsselectedsubsetsP.isEmpty() ? windowrectreal : subsetrect); if (printrect == null) return; TN.emitMessage("UpdatePrintingRectangle " + printrect.toString()); //ResetDIR((TN.currprintdir == null)); // initialize // ignore sketchLocOffset realpaperscale = TN.defaultrealposterpaperscale; // was lrealposterpaperscale which actually applies to the included edges and we're used to the 1000 fold scale in this field trueheight = printrect.getHeight() / TN.CENTRELINE_MAGNIFICATION / realpaperscale; truewidth = printrect.getWidth() / TN.CENTRELINE_MAGNIFICATION / realpaperscale; tftruesize.setText(String.format("%.3fm x %.3fm", truewidth, trueheight)); Updatefinalsize(lastpixfield); } ///////////////////////////////////////////// static int aaa = 0; boolean Updatefinalsize(int lpixfield) { if (lpixfield == 0) { dpmetre = -1.0; try { dpmetre = Float.parseFloat(dpifield.getText()) * 1000.0 / 25.4; } // there's some compiler problem when using Double.parseDouble catch(NumberFormatException e) {;} if (dpmetre <= 0.0) return false; pixelheight = (int)Math.ceil(trueheight * dpmetre); pixelwidth = (int)Math.ceil(truewidth * dpmetre); tfpixelswidth.setText(String.valueOf(pixelwidth)); tfpixelsheight.setText(String.valueOf(pixelheight)); } else { int dppix = -1; try { dppix = Integer.parseInt(lpixfield == 1 ? tfpixelswidth.getText() : tfpixelsheight.getText()); } catch(NumberFormatException e) {;} if (dppix <= 0) return false; if (lpixfield == 1) { pixelwidth = dppix; dpmetre = pixelwidth / truewidth; pixelheight = (int)Math.ceil(trueheight * dpmetre); tfpixelsheight.setText(String.valueOf(pixelheight)); } else { pixelheight = dppix; dpmetre = pixelheight / trueheight; pixelwidth = (int)Math.ceil(truewidth * dpmetre); tfpixelswidth.setText(String.valueOf(pixelwidth)); } dpifield.setText(String.valueOf((float)(dpmetre * 25.4 / 1000.0))); } lastpixfield = lpixfield; return true; } ///////////////////////////////////////////// class pixfieldlisten implements ActionListener, DocumentListener { int pixfield; pixfieldlisten(int lpixfield) { pixfield = lpixfield; } public void actionPerformed(ActionEvent e) { Updatefinalsize(pixfield); } public void insertUpdate(DocumentEvent e) { //if (e.source.hasFocus()) Updatefinalsize(pixfield); } public void removeUpdate(DocumentEvent e) { //if (e.object.hasFocus()) Updatefinalsize(pixfield); } public void changedUpdate(DocumentEvent e) { //if (e.object.hasFocus()) Updatefinalsize(pixfield); } }; ///////////////////////////////////////////// boolean OutputSVG(FileAbstraction fa) throws IOException { LineOutputStream los = new LineOutputStream(fa, "UTF-8"); //new SVGPaths(los, sketchdisplay.sketchgraphicspanel.tsketch.vpaths); SvgGraphics2D svgg2d = new SvgGraphics2D(los, (chTransparentBackground.isSelected() ? "#dddddd" : null)); GraphicsAbstraction ga = new GraphicsAbstraction(svgg2d); float scalefactor = Float.parseFloat(dpifield.getText()); svgg2d.writeheader((float)printrect.getX(), (float)printrect.getY(), (float)printrect.getWidth(), (float)printrect.getHeight(), scalefactor); sketchdisplay.sketchgraphicspanel.tsketch.paintWqualitySketch(ga, sketchdisplay.printingpanel.cbRenderingQuality.getSelectedIndex(), sketchdisplay.sketchlinestyle.subsetattrstylesmap); svgg2d.writefooter(); los.close(); return true; } ///////////////////////////////////////////// boolean OutputSVGnew(FileAbstraction fa) throws IOException { try { float scalefactor = Float.parseFloat(dpifield.getText()); SVGnew svgnew = new SVGnew(fa, chTransparentBackground.isSelected(), scalefactor, printrect, sketchdisplay.printingpanel.cbRenderingQuality.getSelectedIndex(), sketchdisplay.sketchlinestyle.subsetattrstylesmap); svgnew.DrawSketch(sketchdisplay.sketchgraphicspanel.tsketch); svgnew.los.close(); return true; } catch (IOException io) {;} return false; } ///////////////////////////////////////////// BufferedImage RenderBufferedImage(int irenderingquality) { int ibitmaptype = cbBitmaptype.getSelectedIndex(); int imageType = (ibitmaptype == 0 ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_USHORT_GRAY); // use of IndexColorModel and TYPE_BYTE_BINARY doesn't work. pixel bash the grey scales into a two tone later BufferedImage bi = new BufferedImage(pixelwidth, pixelheight, imageType); Graphics2D g2d = bi.createGraphics(); if (chTransparentBackground.isSelected()) { Composite tcomp = g2d.getComposite(); // preserve the composite in order to clear it System.out.println("What is composite: " + tcomp.toString() + " "); //g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0F)); g2d.setComposite(AlphaComposite.Clear); g2d.fill(new Rectangle(0, 0, pixelwidth, pixelheight)); g2d.setComposite(AlphaComposite.SrcOver); } else { g2d.setColor(Color.white); // could make it a different colour g2d.fill(new Rectangle(0, 0, pixelwidth, pixelheight)); } g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, (chAntialiasing.isSelected() ? RenderingHints.VALUE_ANTIALIAS_ON : RenderingHints.VALUE_ANTIALIAS_OFF)); // work out the relative translations to the other subsets // set the pre transformation aff.setToTranslation(pixelwidth / 2, pixelheight / 2); double scchange = printrect.getWidth() / (pixelwidth - 2); aff.scale(1.0F / scchange, 1.0F / scchange); aff.translate(-(printrect.getX() + printrect.getWidth() / 2), -(printrect.getY() + printrect.getHeight() / 2)); g2d.setTransform(aff); GraphicsAbstraction ga = new GraphicsAbstraction(g2d); sketchdisplay.sketchgraphicspanel.tsketch.paintWqualitySketch(ga, irenderingquality, sketchdisplay.sketchlinestyle.subsetattrstylesmap); // flatten all the alpha values (can't find any other way to do this than by pixel bashing) WritableRaster awr = bi.getAlphaRaster(); //srcRaster.getNumBands() if (ibitmaptype == 2) { WritableRaster wr = bi.getRaster(); for (int ix = 0; ix < wr.getWidth(); ix++) for (int iy = 0; iy < wr.getHeight(); iy++) { if (wr.getSample(ix, iy, 0) < 65000) // two bytes wr.setSample(ix, iy, 0, 0); } } else if (chTransparentBackground.isSelected() && (awr != null) && (awr.getNumBands() == 1)) { for (int ix = 0; ix < awr.getWidth(); ix++) for (int iy = 0; iy < awr.getHeight(); iy++) { if (awr.getSample(ix, iy, 0) != 0) awr.setSample(ix, iy, 0, 255); } } return bi; } ///////////////////////////////////////////// void AutoOutputPNG() { int irenderingquality = cbRenderingQuality.getSelectedIndex(); // loops through all selected subsets and creates an image for each one FileAbstraction fa = FileAbstraction.MakeDirectoryAndFileAbstraction(TN.currprintdir, tfdefaultsavename.getText()); fa = fa.SaveAsDialog(SvxFileDialog.FT_BITMAP, sketchdisplay, false); if (fa == null) return; ResetDIR(false); List lsubsets = new ArrayList(); lsubsets.addAll(sketchdisplay.selectedsubsetstruct.vsselectedsubsetsP); OneSketch tsketch = sketchdisplay.sketchgraphicspanel.tsketch; for (String lsubset : lsubsets) { sketchdisplay.selectedsubsetstruct.UpdateSingleSubsetSelection(lsubset); // done in update sketchdisplay.printingpanel.UpdatePrintingRectangle(tsketch.sketchLocOffset, tsketch.realposterpaperscale); // then build it BufferedImage bi = RenderBufferedImage(irenderingquality); String ftype = TN.getSuffix(fa.getName()).substring(1).toLowerCase(); try { FileAbstraction lfa = FileAbstraction.MakeDirectoryAndFileAbstraction(TN.currprintdir, lsubset + ".png"); TN.emitMessage("Writing file " + lfa.getAbsolutePath()); ImageIO.write(bi, ftype, lfa.localfile); } catch (IOException e) { e.printStackTrace(); } } // finalize (return to normality) sketchdisplay.selectedsubsetstruct.UpdateTreeSubsetSelection(sketchdisplay.subsetpanel.pansksubsetstree); sketchdisplay.sketchgraphicspanel.RedoBackgroundView(); } ///////////////////////////////////////////// // irenderingquality = 0 Quick draw, 1 Show images, 2 Update styles, 3 Full draw // stype = "png", "svg", "svgnew" boolean OutputIMG(String stype, int irenderingquality, boolean bAuto) { // dispose of finding the file first FileAbstraction fa = FileAbstraction.MakeDirectoryAndFileAbstraction(TN.currprintdir, tfdefaultsavename.getText()); TN.emitMessage("DSN: " + tfdefaultsavename.getText() + " " + irenderingquality); fa = fa.SaveAsDialog((!stype.equals("png") ? SvxFileDialog.FT_VECTOR : SvxFileDialog.FT_BITMAP), sketchdisplay, bAuto); // this is where the default .png setting is done if (fa == null) return false; ResetDIR(false); // we have to make it as far as the areas so that we can filter by their subsets and render the symbols only in those which apply sketchdisplay.mainbox.UpdateSketchFrames(sketchdisplay.sketchgraphicspanel.tsketch, SketchGraphics.SC_UPDATE_ALL_BUT_SYMBOLS); String ftype = TN.getSuffix(fa.getName()).substring(1).toLowerCase(); try { if (ftype.equals("svg")) { // then build it if ((irenderingquality == 2) || (irenderingquality == 3)) sketchdisplay.mainbox.UpdateSketchFrames(sketchdisplay.sketchgraphicspanel.tsketch, (irenderingquality == 3 ? SketchGraphics.SC_UPDATE_ALL : SketchGraphics.SC_UPDATE_ALL_BUT_SYMBOLS)); if (stype.equals("svgnew")) return OutputSVGnew(fa); return OutputSVG(fa); } BufferedImage bi = RenderBufferedImage(irenderingquality); TN.emitMessage("Writing file " + fa.getAbsolutePath() + " with type " + ftype); ImageIO.write(bi, ftype, fa.localfile); } catch (Exception e) { TN.emitWarning(e.toString()); e.printStackTrace(); return false; } return true; } ///////////////////////////////////////////// void ListImageFormats() // for some reason I can't do JPG output { String[] wfnlist = ImageIO.getWriterFormatNames(); for (int i = 0; i < wfnlist.length; i++) System.out.println("JJJJJ " + wfnlist[i]); } ///////////////////////////////////////////// void UploadPNG(boolean btomjgoverlay) { int irenderingquality = cbRenderingQuality.getSelectedIndex(); OneSketch tsketch = sketchdisplay.sketchgraphicspanel.tsketch; // then build it if ((irenderingquality == 2) || (irenderingquality == 3)) sketchdisplay.mainbox.UpdateSketchFrames(tsketch, (irenderingquality == 3 ? SketchGraphics.SC_UPDATE_ALL : SketchGraphics.SC_UPDATE_ALL_BUT_SYMBOLS)); BufferedImage bi = RenderBufferedImage(irenderingquality); // String ftype = TN.getSuffix(fa.getName()).substring(1).toLowerCase(); try { //FileAbstraction.postData("http://seagrass.goatchurch.org.uk/~mjg/cgi-bin/uploadtiles.py", bi); //String response = FileAbstraction.postData("http://10.0.0.10/expo-cgi-bin/tunserv.py", tfdefaultsavename.getText(), bi); //TN.emitMessage("Writing file " + fa.getAbsolutePath() + " with type " + ftype); String filename = tfdefaultsavename.getText(); FileAbstraction fimageas; if (btomjgoverlay) { String lspatial_reference_system = "OS Grid SD"; // for Ireby (Yorkshire) double lspatial_reference_systemXoffset = 0; double lspatial_reference_systemYoffset = 0; for (OnePath op : tsketch.vpaths) { if (!((op.linestyle == SketchLineStyle.SLS_CONNECTIVE) && (op.plabedl != null) && op.plabedl.sfontcode.equals("survey") && !op.plabedl.drawlab.equals(""))) continue; int isrs = op.plabedl.drawlab.indexOf("spatial_reference_system"); //System.out.println(isrs + " drawlab: " + op.plabedl.drawlab); if (isrs == -1) continue; isrs += "spatial_reference_system".length(); while ((isrs < op.plabedl.drawlab.length()) && ((op.plabedl.drawlab.charAt(isrs) == ' ') || (op.plabedl.drawlab.charAt(isrs) == '='))) isrs++; //System.out.println(isrs); if (isrs >= op.plabedl.drawlab.length()) continue; if (op.plabedl.drawlab.charAt(isrs) != '"') continue; int isrse = op.plabedl.drawlab.indexOf('"', isrs + 1); //System.out.println(isrse); if ((isrse != -1) && (isrse - isrs < 200)) lspatial_reference_system = op.plabedl.drawlab.substring(isrs + 1, isrse); else continue; // now extract the two following values lspatial_reference_systemXoffset = 0.0; lspatial_reference_systemYoffset = 0.0; while ((isrse < op.plabedl.drawlab.length()) && ((op.plabedl.drawlab.charAt(isrs) == ' ') || (op.plabedl.drawlab.charAt(isrs) == ','))) isrse++; int isrse1 = isrse; while ((isrse1 < op.plabedl.drawlab.length()) && (((op.plabedl.drawlab.charAt(isrse1) >= '0') && (op.plabedl.drawlab.charAt(isrse1) <= '9')) || (op.plabedl.drawlab.charAt(isrse1) == '-') || (op.plabedl.drawlab.charAt(isrse1) == '+') || (op.plabedl.drawlab.charAt(isrse1) == '.'))) isrse1++; String sXoffset = op.plabedl.drawlab.substring(isrse, isrse1); isrse = isrse1; while ((isrse < op.plabedl.drawlab.length()) && ((op.plabedl.drawlab.charAt(isrs) == ' ') || (op.plabedl.drawlab.charAt(isrs) == ','))) isrse++; isrse1 = isrse; while ((isrse1 < op.plabedl.drawlab.length()) && (((op.plabedl.drawlab.charAt(isrse1) >= '0') && (op.plabedl.drawlab.charAt(isrse1) <= '9')) || (op.plabedl.drawlab.charAt(isrse1) == '-') || (op.plabedl.drawlab.charAt(isrse1) == '+') || (op.plabedl.drawlab.charAt(isrse1) == '.'))) isrse1++; String sYoffset = op.plabedl.drawlab.substring(isrse, isrse1); if (!sXoffset.equals("") || !sYoffset.equals("")) { try { lspatial_reference_systemXoffset = Double.valueOf(sXoffset); lspatial_reference_systemYoffset = Double.valueOf(sYoffset); } catch(NumberFormatException e) { TN.emitWarning(e.toString()); } } } TN.emitMessage(lspatial_reference_system + " " + lspatial_reference_systemXoffset + " " + lspatial_reference_systemYoffset); NetConnection.upmjgirebyoverlay(bi, filename, dpmetre / realpaperscale, printrect.getX() / TN.CENTRELINE_MAGNIFICATION + tsketch.sketchLocOffset.x, -printrect.getY() / TN.CENTRELINE_MAGNIFICATION + tsketch.sketchLocOffset.y, lspatial_reference_system); } else { String target = TN.troggleurl + "jgtuploadfile"; fimageas = NetConnection.uploadFile(FileAbstraction.MakeOpenableFileAbstraction(target), "tileimage", filename + ".png", bi, null); TN.emitMessage("Image was saved as :" + fimageas.getPath() + ":"); } } catch (Exception e) { e.printStackTrace(); } } } tunnelx-20140102.orig/src/TNXML.java0000644000000000000000000007313712261213471013635 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; class TNXML { static String sHEADER = ""; //static String sHEADER = ""; static String sFONTCOLOURS = "fontcolours"; static String sSURVEXEXEDIR = "survex_executable_directory"; static String sDIRECTORY_APPLICATION = "application"; static String sDIRECTORY = "directory"; static String sTUNNELVERSION = "tunnelversion"; static String sTUNNELUSER = "tunneluser"; static String sTUNNELPROJECT = "tunnelproject"; static String sTUNNELDATE = "tunneldate"; static String sTUNNELXML = "tunnelxml"; static String sSET = "set"; static String sFLOAT_VALUE = "fval"; static String sTEXT = "text"; static String sNAME = "name"; static String sEXPORTS = "exports"; static String sEXPORT = "export"; static String sEXPORT_FROM_STATION = "estation"; static String sEXPORT_TO_STATION = "ustation"; static String sSKSUBSET = "sketchsubset"; static String sSKSNAME = "subname"; static String sSKIMPORTFROM = "importfrom"; static String sMEASUREMENTS = "measurements"; static String sSVX_DATE = "date"; static String sSVX_TITLE = "title"; static String sSVX_TAPE_PERSON = "tapeperson"; static String sLEG = "leg"; // effectively the same as set static String sFIX = "fix"; static String sPOS_FIX = "pos_fix"; static String sFROM_STATION = "from"; static String sTO_STATION = "to"; static String sTAPE = "tape"; static String sCOMPASS = "compass"; static String sCLINO = "clino"; static String sDEPTHS = "depths"; static String sTITLESET = "titleset"; static String sFROMFLOAT_VALUE = "fval_from"; static String sTOFLOAT_VALUE = "fval_to"; // additional tube modelling stuff static String sXSECTION = "xsection"; static String sXSECTION_INDEX = "xsind"; // prefer to be the index. static String sXS_STATION0 = "xsst0"; static String sXS_STATION1 = "xsst1"; static String sXS_STATION_LAM = "xs_lam"; static String sXS_STATION_ORIENT_FORE = "xsstorfore"; static String sXS_STATION_ORIENT_BACK = "xsstorback"; static String sXS_STATION_ORIENT_REL_COMPASS = "xsstorrelc"; static String sXS_STATION_ORIENT_CLINO = "xsstorclin"; static String sLINEAR_TUBE = "ltube"; static String sFROM_XSECTION = "xsfrom"; static String sTO_XSECTION = "xsto"; static String sSKETCH = "sketch"; static String sSKETCH_LOCOFFSETX = "locoffsetx"; static String sSKETCH_LOCOFFSETY = "locoffsety"; static String sSKETCH_LOCOFFSETZ = "locoffsetz"; static String sSKETCH_REALPAPERSCALE = "realpaperscale"; // defunct set static String sSKETCH_BACK_IMG = "backimage"; static String sSKETCH_BACK_IMG_FILE = "imgfile"; static String sSKETCH_BACK_IMG_FILE_SELECTED = "selected"; static String sAFFINE_TRANSFORM = "affinetrans"; static String sAFTR_M00 = "aftrm00"; static String sAFTR_M01 = "aftrm10"; static String sAFTR_M10 = "aftrm01"; static String sAFTR_M11 = "aftrm11"; static String sAFTR_M20 = "aftrm20"; static String sAFTR_M21 = "aftrm21"; static String sSKETCH_PATH = "skpath"; static String sFROM_SKNODE = "from"; static String sTO_SKNODE = "to"; static String sSPLINED = "splined"; static String sSK_LINESTYLE = "linestyle"; // values of linestyle. static String vsLS_CENTRELINE = "centreline"; static String vsLS_WALL = "wall"; static String vsLS_ESTWALL = "estwall"; static String vsLS_PITCHBOUND = "pitchbound"; static String vsLS_CEILINGBOUND = "ceilingbound"; static String vsLS_DETAIL = "detail"; static String vsLS_INVISIBLE = "invisible"; static String vsLS_CONNECTIVE = "connective"; static String vsLS_FILLED = "filled"; // this supercedes the "label" and takes out the local label xml problem. static String sPATHCODES = "pathcodes"; static String sCL_STATIONS = "cl_stations"; static String sCL_TAIL = "tail"; static String sCL_HEAD = "head"; static String sCL_ELEV = "elev"; static String sPC_TEXT = "pctext"; static String sLTEXTSTYLE = "style"; static String sPC_NODEPOSXREL = "nodeposxrel"; static String sPC_NODEPOSYREL = "nodeposyrel"; static String sPC_ARROWPRES = "arrowpres"; static String sPC_BOXPRES = "boxpres"; static String sPC_RSYMBOL = "pcsymbol"; static String sLRSYMBOL_NAME = "rname"; static String sPC_AREA_SIGNAL = "pcarea"; static String sAREA_PRESENT = "area_signal"; static String sASIGNAL_KEEPAREA = "keeparea"; static String sASIGNAL_KILLAREA = "killarea"; static String sASIGNAL_OUTLINEAREA = "outlinearea"; static String sASIGNAL_HCOINCIDE = "hcoincide"; static String sASIGNAL_ZSETRELATIVE = "zsetrelative"; static String sASIG_NODECONN_ZSETRELATIVE = "nodeconnzsetrelative"; static String sASIGNAL_SKETCHFRAME = "sketchframe"; static String sASIG_FRAME_SCALEDOWN = "sfscaledown"; static String sASIG_FRAME_ROTATEDEG = "sfrotatedeg"; static String sASIG_FRAME_ELEVROTDEG = "sfelevrotdeg"; static String sASIG_FRAME_ELEVVERTPLANE = "sfelevvertplane"; static String sASIG_FRAME_XTRANS = "sfxtrans"; static String sASIG_FRAME_YTRANS = "sfytrans"; static String sASIG_FRAME_SKETCH = "sfsketch"; static String sASIG_FRAME_STYLE = "sfstyle"; static String sASIG_FRAME_IMGPIXELWIDTH = "sfpixwidth"; static String sASIG_FRAME_IMGPIXELHEIGHT = "sfpixheight"; static String sASIGNAL_ELEVATIONPATH = "elevationpath"; // these are deprecated (but read from the local mangled xml) static String sLRSYMBOL = "rsymbol"; static String sLTEXT = "text"; static String sLABEL = "label"; static String sTAIL = "tail"; static String sHEAD = "head"; static String sSPREAD = "spread"; // the new symbol stuff laid out inside the label // these will be deleted static String sLSYMBOL = "symbol"; static String sLSYMBOL_NAME = "name"; static String sLMCODE = "mcode"; static String sLQUANTITY = "qty"; static String sLASYMBOL = "asymbol"; static String sLAUT_SYMBOL_ORIENTATION = "orientation"; static String sLAUT_SYMBOL_FIXED = "fixed"; static String sLAUT_SYMBOL_RANDOM = "random"; static String sLAUT_SYMBOL_ALONGAXIS = "alongaxis"; static String sLAUT_SYMBOL_ALONGAXIS_PERP = "alongaxisperp"; static String sLAUT_SYMBOL_CLOSESTFROMAXIS = "closestfromaxis"; static String sLAUT_SYMBOL_CLOSESTALONGAXIS = "closestalongaxis"; static String sLAUT_SYMBOL_NEARAXIS = "nearaxis"; static String sLAUT_SYMBOL_SCALE = "scale"; static String sLAUT_SYMBOL_ANDHALF = "andhalf"; static String sLAUT_SYMBOL_PICSCALE = "picscale"; static String sLAUT_SYMBOL_AXISSCALE = "axisscale"; static String sLAUT_SYMBOL_AXISSCALEPERP = "axisscaleperp"; static String sLAUT_SYMBOL_POSITION = "position"; static String sLAUT_SYMBOL_ENDPATH = "endpath"; static String sLAUT_SYMBOL_LATTICE = "lattice"; // lattice relative to endpoint static String sLAUT_SYMBOL_LATTICEF = "latticef"; // lattice fixed to an integral phase (so will always be consistent) static String sLAUT_SYMBOL_ALONGPATH_RANDOM_PULLBACK = "alongpath_random_pullback"; static String sLAUT_SYMBOL_ALONGPATH_EVEN = "alongpath_even"; static String sLAUT_SYMBOL_PULLBACK = "pullback"; static String sLAUT_SYMBOL_PUSHOUT = "pushout"; static String sLAUT_SYMBOL_MULTIPLICITY = "multiplicity"; static String sLAUT_SYMBOL_MULTIPLICITY_FILL = "fill"; static String sLAUT_SYMBOL_AINT = "area-interaction"; static String sLAUT_SYMBOL_AINT_NO_OVERLAP = "no-overlap"; static String sLAUT_SYMBOL_AINT_TRIM = "trim"; static String sLAUT_SYMBOL_AINT_ALLOWED_OUTSIDE = "allowed-outside"; static String sLAUT_SYMBOL_AINT_ALLOWED_OUTSIDE_NO_OVERLAP = "allowed-outside-no-overlap"; static String sLAUT_SYMBOL_AREA_FILL = "symbolareafillcolour"; static String sLAUT_SYMBOL_DRAWSTYLE = "drawstyle"; static String sLAUT_SYMBOL_DRAWSTYLE_FILLED = "filled"; static String sLAUT_SYMBOL_DRAWSTYLE_LINE = "line"; // aut symbols which reference the above static String sLAUT_SYMBOL = "symbolaut"; static String sLAUT_SYMBOL_NAME = "dname"; static String sLAUT_DESCRIPTION = "description"; static String sLAUT_SYMBOLS = "aut-symbols"; static String sLAUT_BUTTON_ACTION = "buttonaction"; static String sLAUT_OVERWRITE = "overwrite"; static String sLAUT_APPEND = "append"; static String sLAUT_NOBUTTON = "nobutton"; static String sSUBSET_ATTRIBUTE_STYLE = "groupsubsetattr"; static String sSUBSET_ATTRIBUTE_STYLE_NAME = "groupsubsetname"; static String sSUBSET_ATTRIBUTE_STYLE_SELECTABLE = "groupsubsetselectable"; // yes or no static String sSUBSET_ATTRIBUTE_STYLE_IMPORT = "importgroupsubsetattr"; static String sSUBSET_ATTRIBUTES = "subsetattr"; static String sSUBSET_NAME = "name"; static String sUPPER_SUBSET_NAME = "uppersubset"; static String sSET_ATTR_VARIABLE = "setvariable"; static String sATTR_VARIABLE_NAME = "name"; static String sATTR_VARIABLE_VALUE = "value"; static String sATTR_VARIABLE_VALUE_CLEAR = "--clear--"; static String sSUBSET_AREAMASKCOLOUR = "areamaskcolour"; static String sSUBSET_AREACOLOUR = "areacolour"; static String sLABEL_STYLE_FCOL = "labelfcol"; static String sLABEL_STYLE_NAME = "labelstylename"; static String sLABEL_FONTNAME = "fontname"; static String sLABEL_FONTSTYLE = "fontstyle"; static String sLABEL_FONTSIZE = "size"; static String sLABEL_COLOUR = "labelcolour"; static String sLINE_STYLE_COL = "linestylecol"; static String sLS_STROKEWIDTH = "strokewidth"; static String sLS_SPIKEGAP = "spikegap"; static String sLS_GAPLENG = "gapleng"; static String sLS_SPIKEHEIGHT = "spikeheight"; static String sLS_STROKECOLOUR = "strokecolour"; static String sLS_SHADOWSTROKEWIDTH = "shadowstrokewidth"; static String sLS_SHADOWSTROKECOLOUR = "shadowstrokecolour"; static String sGRID_DEF = "grid_def"; static String sMAX_GRID_LINES = "maxgridlines"; static String sGRID_XORIG = "xorig"; static String sGRID_YORIG = "yorig"; static String sGRID_SPACING = "gridspacing"; static String sGRID_SPACING_WIDTH = "gswidth"; static String sAREA_SIG_DEF = "area_signal_def"; static String sAREA_SIG_NAME = "asigname"; static String sAREA_SIG_EFFECT = "asigeffect"; static String sIMAGE_FILE_DIRECTORY = "image_file_directory"; static String sIMAGE_FILE_DIRECTORY_NAME = "name"; static String sPOINT = "pt"; static String sPTX = "X"; static String sPTY = "Y"; static String sPTZ = "Z"; static String[] tabs = { "", "\t", "\t\t", "\t\t\t", "\t\t\t\t" }; ///////////////////////////////////////////// static String EncodeLinestyle(int linestyle) { switch (linestyle) { case SketchLineStyle.SLS_CENTRELINE: return vsLS_CENTRELINE; case SketchLineStyle.SLS_WALL: return vsLS_WALL; case SketchLineStyle.SLS_ESTWALL: return vsLS_ESTWALL; case SketchLineStyle.SLS_PITCHBOUND: return vsLS_PITCHBOUND; case SketchLineStyle.SLS_CEILINGBOUND: return vsLS_CEILINGBOUND; case SketchLineStyle.SLS_DETAIL: return vsLS_DETAIL; case SketchLineStyle.SLS_INVISIBLE: return vsLS_INVISIBLE; case SketchLineStyle.SLS_CONNECTIVE: return vsLS_CONNECTIVE; case SketchLineStyle.SLS_FILLED: return vsLS_FILLED; default: TN.emitError("Unknown linestyle"); } return "??"; } ///////////////////////////////////////////// static int DecodeLinestyle(String slinestyle) { if (slinestyle.equals(vsLS_CENTRELINE)) return SketchLineStyle.SLS_CENTRELINE; if (slinestyle.equals(vsLS_WALL)) return SketchLineStyle.SLS_WALL; if (slinestyle.equals(vsLS_ESTWALL)) return SketchLineStyle.SLS_ESTWALL; if (slinestyle.equals(vsLS_PITCHBOUND)) return SketchLineStyle.SLS_PITCHBOUND; if (slinestyle.equals(vsLS_CEILINGBOUND)) return SketchLineStyle.SLS_CEILINGBOUND; if (slinestyle.equals(vsLS_DETAIL)) return SketchLineStyle.SLS_DETAIL; if (slinestyle.equals(vsLS_INVISIBLE)) return SketchLineStyle.SLS_INVISIBLE; if (slinestyle.equals(vsLS_CONNECTIVE)) return SketchLineStyle.SLS_CONNECTIVE; if (slinestyle.equals(vsLS_FILLED)) return SketchLineStyle.SLS_FILLED; // backwards compatibility for now. TN.emitWarning("numeric linestyle " + slinestyle); return Integer.parseInt(slinestyle); } ///////////////////////////////////////////// ///////////////////////////////////////////// static StringBuffer sb = new StringBuffer(); // Builders are like Buffers but they don't do thread-safety checks, so they're faster to run in single-threaded programs like this one ///////////////////////////////////////////// static void sbstartxcom(StringBuffer sb, int indent, String command) { sb.setLength(0); sb.append(tabs[indent]); sb.append('<'); sb.append(command); } ///////////////////////////////////////////// static String attribxcom(String attr, String val) { return " " + attr + "=\"" + xmanglxmltext(val) + "\""; } ///////////////////////////////////////////// static void sbattribxcom(StringBuffer sb, String attr, String val) { sb.append(" "); sb.append(attr); sb.append("=\""); xmanglxmltextSB(sb, val, false); sb.append("\""); } ///////////////////////////////////////////// static String sbendxcomsingle(StringBuffer sb) { sb.append("/>"); return sb.toString(); } ///////////////////////////////////////////// static String sbendxcom(StringBuffer sb) { sb.append(">"); return sb.toString(); } ///////////////////////////////////////////// // annoying ...args feature available only in 1.5, so makes it difficult to detune it ///////////////////////////////////////////// static String xcomN(int indent, String command, String[] args, int N) { if((N % 2) != 0) { TN.emitWarning("Malformed call to XML library, command="+command+" N="+N); return ""; } sbstartxcom(sb, indent, command); for(int i = 0; i < N/2; i++) sbattribxcom(sb, args[2*i], args[2*i + 1]); return sbendxcomsingle(sb); } ///////////////////////////////////////////// static String xcomopenN(int indent, String command, String[] args, int N) { if((N % 2) != 0) { TN.emitWarning("Malformed call to XML library"); //System.exit(1); return ""; } sbstartxcom(sb, indent, command); for(int i = 0; i < N/2; i++) sbattribxcom(sb, args[2*i], args[2*i + 1]); return sbendxcom(sb); } ///////////////////////////////////////////// static String xcomtextN(int indent, String command, String[] args, int N) { if((N % 2) != 1) { TN.emitWarning("Malformed call to XML library"); return ""; } sbstartxcom(sb, indent, command); for(int i = 0; i < (N-1)/2; i++) sbattribxcom(sb, args[2*i], args[2*i + 1]); sb.append(">"); sb.append(args[N-1]); sb.append("" + text + ""; } ///////////////////////////////////////////// // quick and dirty extraction here. (the two command things could be buffered). static String xrawextracttext(String source, String commandopen, String commandclose) { int p0 = source.indexOf(commandopen); int p0g = p0 + commandopen.length(); int p1 = source.lastIndexOf(commandclose); if ((p0 != -1) && (p1 != -1) && (p0g < p1)) return source.substring(p0g, p1); return null; } ///////////////////////////////////////////// static String xrawextracttext(String source, String command) { return xrawextracttext(source, xcomopen(0, command), xcomclose(0, command)); } ///////////////////////////////////////////// // this is very brittle stuff to extract one closed command static String xrawextractattr(String source, String[] val, String command, String[] attr) { int pe = source.indexOf("/>"); int ps = source.indexOf(command); if ((pe == -1) || (ps == -1) || (pe <= ps)) return null; for (int i = 0; i < attr.length; i++) { int pa = source.indexOf(attr[i]); val[i] = null; if ((pa != -1) && (pa < pe)) { int pq1 = source.indexOf("\"", pa); int pq2 = source.indexOf("\"", pq1 + 1); if ((pq1 < pq2) && (pq2 < pe)) val[i] = source.substring(pq1 + 1, pq2); } } return source.substring(pe + 2).trim(); } ///////////////////////////////////////////// static char[] chconvCH = { (char)176, (char)246, (char)252, '<', '>', '"', '&', '\\', '\'', '\n', '\t', ' ' }; static char[] chconv = chconvCH; // allow for hacks (which vary chconvleng) static String[] chconvName = {"°", "ö", "ü", "<", ">", """, "&", "&backslash;", "&apostrophe;", "&newline;", "&tab;", "&space;" }; static int chconvleng = chconvCH.length; // used for hacking out the space ones (this hack needs to be killed, or replaced with a flag) static int chconvlengWSP = chconvCH.length - 4; // used for hacking out the space ones (this hack needs to be killed, or replaced with a flag) ///////////////////////////////////////////// static void xmanglxmltextSB(StringBuffer sb, String s, boolean bAlsoSpace) { assert ((chconvleng == chconvName.length) || (chconvleng == chconvlengWSP)); for (int i = 0; i < s.length(); i++) { char ch = s.charAt(i); int j; // there might be a regexp that would do this substitution directly, or use indexOf in a concatenated string of chconvCH for (j = 0; j < chconvleng; j++) { if ((ch == chconvCH[j]) && (bAlsoSpace || (ch != ' '))) { sb.append(chconvName[j]); break; } } if (j == chconvleng) sb.append(ch); } } ///////////////////////////////////////////// static String xmanglxmltext(String s) { sb.setLength(0); xmanglxmltextSB(sb, s, true); return sb.toString(); } ///////////////////////////////////////////// static String xunmanglxmltext(String s) { if (s.indexOf('&') == -1) return s; sb.setLength(0); for (int i = 0; i < s.length(); i++) { char ch = s.charAt(i); if (ch == '&') { int j; for (j = 0; j < chconvleng; j++) { if (s.regionMatches(i, chconvName[j], 0, chconvName[j].length())) { sb.append(chconvCH[j]); i += chconvName[j].length() - 1; //if (j < 2) // System.out.println(chconv[j] + " -- " + (int)chconv[j].toCharArray()[0]); break; } } if (j == chconvleng) { if (s.regionMatches(i, "&space;", 0, 7)) // back-compatible { sb.append(" "); i += 6; } else { System.out.println(s.substring(i)); TN.emitError("unable to resolve & from pos " + i + " in string:" + s); } } } else sb.append(ch); } return sb.toString(); } }; tunnelx-20140102.orig/src/SketchFrameDef.java0000644000000000000000000010171512261213471015540 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.io.StringReader; import java.io.IOException; import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.ArrayList; import java.util.Collections; import java.util.Stack; import java.awt.Graphics; import java.awt.FontMetrics; import java.awt.Font; import java.awt.Color; import java.awt.Dimension; import java.awt.geom.Line2D; import java.awt.geom.GeneralPath; import java.awt.geom.Point2D; //import java.awt.geom.Line2D.Float; import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D.Float; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.awt.geom.NoninvertibleTransformException; ///////////////////////////////////////////// class ElevCLine implements Comparable { GeneralPath gp; double tz0; double tz1; String csubset; int linestyle; SubsetAttr subsetattr; ElevCLine(OnePath op, Vec3 sketchLocOffset, double coselevrot, double sinelevrot) { linestyle = op.linestyle; csubset = (op.vssubsets.isEmpty() ? "" : op.vssubsets.get(op.vssubsets.size() - 1)); subsetattr = op.subsetattr; double x0 = op.pnstart.pn.getX() + sketchLocOffset.x * TN.CENTRELINE_MAGNIFICATION; double y0 = op.pnstart.pn.getY() - sketchLocOffset.y * TN.CENTRELINE_MAGNIFICATION; double z0 = op.pnstart.zalt + sketchLocOffset.z * TN.CENTRELINE_MAGNIFICATION; double x1 = op.pnend.pn.getX() + sketchLocOffset.x * TN.CENTRELINE_MAGNIFICATION; double y1 = op.pnend.pn.getY() - sketchLocOffset.y * TN.CENTRELINE_MAGNIFICATION; double z1 = op.pnend.zalt + sketchLocOffset.z * TN.CENTRELINE_MAGNIFICATION; double tx0 = coselevrot * x0 + sinelevrot * y0; double ty0 = -sinelevrot * x0 + coselevrot * y0; double tx1 = coselevrot * x1 + sinelevrot * y1; double ty1 = -sinelevrot * x1 + coselevrot * y1; gp = new GeneralPath(); float[] pco = op.GetCoords(); gp.moveTo(tx0 - sketchLocOffset.x * TN.CENTRELINE_MAGNIFICATION, -z0 + sketchLocOffset.y * TN.CENTRELINE_MAGNIFICATION); assert ((linestyle != SketchLineStyle.SLS_CENTRELINE) || (op.nlines == 1)); for (int i = 0; i < op.nlines; i++) { double lam = i * 1.0 / op.nlines; // maybe by along projection, unless ends are close together like it's a loop double zi = z0 * (1.0 - lam) + z1 * lam; double tiltx = pco[i * 2]; double tilty = pco[i * 2 + 1]; double xi = pco[i * 2] + sketchLocOffset.x * TN.CENTRELINE_MAGNIFICATION; double yi = pco[i * 2 + 1] - sketchLocOffset.y * TN.CENTRELINE_MAGNIFICATION; double txi = coselevrot * x0 + sinelevrot * y0; //double tyi = -sinelevrot * x0 + coselevrot * y0; //cline = new Line2D.Double(tx0, -z0, tx1, -z1); // put back into same coordinate framework so offsets (in the 90, 180 and 360 directions are consistent and can be aligned //cline = new Line2D.Double(tx0 - sketchLocOffset.x * TN.CENTRELINE_MAGNIFICATION, -z0 + sketchLocOffset.y * TN.CENTRELINE_MAGNIFICATION, // tx1 - sketchLocOffset.x * TN.CENTRELINE_MAGNIFICATION, -z1 + sketchLocOffset.y * TN.CENTRELINE_MAGNIFICATION); gp.lineTo(txi - sketchLocOffset.x * TN.CENTRELINE_MAGNIFICATION, -zi + sketchLocOffset.y * TN.CENTRELINE_MAGNIFICATION); } gp.lineTo(tx1 - sketchLocOffset.x * TN.CENTRELINE_MAGNIFICATION, -z1 + sketchLocOffset.y * TN.CENTRELINE_MAGNIFICATION); tz0 = ty0; tz1 = ty1; } ///////////////////////////////////////////// public int compareTo(ElevCLine ecl) { double zdiff = (tz0 + tz1) - (ecl.tz0 + ecl.tz1); return (zdiff > 0.0 ? 1 : (zdiff < 0.0 ? -1 : 0)); } } //////////////////////////////////////////////////////////////////////////////// class SketchFrameDef { float sfscaledown = 1.0F; float sfrotatedeg = 0.0F; float sfelevrotdeg = 0.0F; // disabled by 0. use 360 to get that direction (only applies to sketches that contain centrelines) String sfelevvertplane = ""; // either blank or "n0n1" for the node pair we are tied to; or "extunfold" for extended mode double sfxtrans = 0.0F; double sfytrans = 0.0F; // could also define a restricted x-y area of the bitmap to plot (esp for the case of cross-sections) AffineTransform pframesketchtrans = null; String sfstyle = ""; Map submapping = new TreeMap(); String sfsketch = ""; OneSketch pframesketch = null; FileAbstraction pframeimage = null; int imagepixelswidth = -1; int imagepixelsheight = -1; float sfnodeconnzsetrelative = 0.0F; int distinctid; // used for the comparator as this is in a hashset static int Sdistinctid = 1; List elevclines = null; ///////////////////////////////////////////// boolean IsImageType() { // no endsWithIgnoreCase function return (sfsketch.toLowerCase().endsWith(TN.SUFF_PNG) || sfsketch.toLowerCase().endsWith(TN.SUFF_JPG)); } ///////////////////////////////////////////// BufferedImage SetImageWidthHeight() { BufferedImage bi = pframeimage.GetImage(true); //System.out.println("FFS " + bi.getWidth() + " " + bi.getHeight()); if (bi.getWidth() != -1) imagepixelswidth = bi.getWidth(); if (bi.getHeight() != -1) imagepixelsheight = bi.getHeight(); return bi; } ///////////////////////////////////////////// String GetToTextV() { StringBuffer sb = new StringBuffer(); TNXML.sbstartxcom(sb, 0, TNXML.sASIGNAL_SKETCHFRAME); sb.append(TN.nl); TNXML.sbattribxcom(sb, TNXML.sASIG_FRAME_SCALEDOWN, String.valueOf(sfscaledown)); sb.append(TN.nl); TNXML.sbattribxcom(sb, TNXML.sASIG_FRAME_ROTATEDEG, String.valueOf(sfrotatedeg)); sb.append(TN.nl); TNXML.sbattribxcom(sb, TNXML.sASIG_FRAME_ELEVROTDEG, String.valueOf(sfelevrotdeg)); sb.append(TN.nl); TNXML.sbattribxcom(sb, TNXML.sASIG_FRAME_ELEVVERTPLANE, sfelevvertplane); sb.append(TN.nl); TNXML.sbattribxcom(sb, TNXML.sASIG_FRAME_XTRANS, String.valueOf(sfxtrans)); sb.append(TN.nl); TNXML.sbattribxcom(sb, TNXML.sASIG_FRAME_YTRANS, String.valueOf(sfytrans)); sb.append(TN.nl); TNXML.sbattribxcom(sb, TNXML.sASIG_NODECONN_ZSETRELATIVE, String.valueOf(sfnodeconnzsetrelative)); sb.append(TN.nl); TNXML.sbattribxcom(sb, TNXML.sASIG_FRAME_SKETCH, sfsketch); sb.append(TN.nl); TNXML.sbattribxcom(sb, TNXML.sASIG_FRAME_STYLE, sfstyle); //if ((imagepixelswidth != -1) || (imagepixelsheight != -1)) { sb.append(TN.nl); TNXML.sbattribxcom(sb, TNXML.sASIG_FRAME_IMGPIXELWIDTH, String.valueOf(imagepixelswidth)); sb.append(TN.nl); TNXML.sbattribxcom(sb, TNXML.sASIG_FRAME_IMGPIXELHEIGHT, String.valueOf(imagepixelsheight)); } TNXML.sbendxcom(sb); sb.append(TN.nl); // sort the mappings by uppersubset, which will be listed first to make them line up List sattrlines = new ArrayList(); for (String ssubset : submapping.keySet()) sattrlines.add(TNXML.xcom(0, TNXML.sSUBSET_ATTRIBUTES, TNXML.sUPPER_SUBSET_NAME, submapping.get(ssubset), TNXML.sSUBSET_NAME, ssubset)); Collections.sort(sattrlines); for (String sattrline : sattrlines) { sb.append(sattrline); sb.append(TN.nl); } sb.append(TNXML.xcomclose(0, TNXML.sASIGNAL_SKETCHFRAME)); return sb.toString(); } ///////////////////////////////////////////// SketchFrameDef() { distinctid = Sdistinctid++; } ///////////////////////////////////////////// void Copy(SketchFrameDef o, boolean bAll) { if (bAll || !o.sfsketch.equals("")) { sfscaledown = o.sfscaledown; sfrotatedeg = o.sfrotatedeg; sfelevrotdeg = o.sfelevrotdeg; sfelevvertplane = o.sfelevvertplane; sfxtrans = o.sfxtrans; sfytrans = o.sfytrans; sfsketch = o.sfsketch; sfstyle = o.sfstyle; sfnodeconnzsetrelative = o.sfnodeconnzsetrelative; imagepixelswidth = o.imagepixelswidth; imagepixelsheight = o.imagepixelsheight; } if (bAll || !o.submapping.isEmpty()) { submapping.clear(); submapping.putAll(o.submapping); } } ///////////////////////////////////////////// SketchFrameDef(SketchFrameDef o) { Copy(o, true); } ///////////////////////////////////////////// // to find the transform of background image/sketch that is in plan or of type n0n1 elevation AffineTransform MakeVertplaneTransform(AffineTransform ucurrtrans, OnePath fop) { if (!sfelevvertplane.equals("n0n1")) { assert (sfelevvertplane.equals("") || sfelevvertplane.equals("extunfold")); return new AffineTransform(ucurrtrans); } assert fop != null; assert fop.plabedl.sketchframedef == this; // normal case float[] pco = fop.GetCoords(); Point2D ptsrc = new Point2D.Double(); Point2D ptdst = new Point2D.Double(); // [ m00x + m01y + m02, m10x + m11y + m12 ] // c=pco[0], v=Norm(pco[2]-pco[0]) // 0,0 -> c = m02, m12 // 1,0 -> c+v = m00+m02, m10+m12 // 0,1 -> c+(0, fac)= m01+m02, m11+m12 ptsrc.setLocation(pco[0], pco[1]); ucurrtrans.transform(ptsrc, ptdst); double m02 = ptdst.getX(); double m12 = ptdst.getY(); double pvx = pco[2] - pco[0]; double pvy = pco[3] - pco[1]; double pvlen = Math.sqrt(pvx*pvx + pvy*pvy); ptsrc.setLocation(pco[0] + pvx/pvlen, pco[1] + pvy/pvlen); ucurrtrans.transform(ptsrc, ptdst); double m00 = ptdst.getX() - m02; double m10 = ptdst.getY() - m12; double scaX = Math.sqrt(ucurrtrans.getScaleX()*ucurrtrans.getScaleX() + ucurrtrans.getShearX()*ucurrtrans.getShearX()); double scaY = Math.sqrt(ucurrtrans.getScaleY()*ucurrtrans.getScaleY() + ucurrtrans.getShearY()*ucurrtrans.getShearY()); double scaTilt = scaY / scaX; assert scaTilt <= 1.001; if (scaTilt > 0.999) scaTilt = 1.0; // edge on case if ((scaTilt == 1.0) || (m00 == 0.0)) return null; ptsrc.setLocation(pco[0], pco[1] + 1.0); ucurrtrans.transform(ptsrc, ptdst); double m01 = 0.0; double m11 = scaX*Math.sqrt(1.0 - scaTilt*scaTilt); return new AffineTransform(m00, m10, m01, m11, m02, m12); } ///////////////////////////////////////////// // there are some unfortunate mixups with the lrealpaperscale used for insetting sketches at scale 1:1000 onto a poster sensibly // which are not good for images (pixels are approx 1:1000) or cross-sections // (n0n1 sfelevvertplane, meaning aligned along node0->node1 of the defining path of the cross-section, pref at scale 1.0 void UpdateSketchFrame(OneSketch lpframesketch, double lrealpaperscale, Vec3 lsketchLocOffset) { pframesketch = lpframesketch; pframesketchtrans = new AffineTransform(); assert (pframesketch == null) || (pframeimage == null); assert sfelevvertplane.equals("") || sfelevvertplane.equals("n0n1") || sfelevvertplane.equals("extunfold"); if (!sfelevvertplane.equals("n0n1")) // for normal background case pframesketchtrans.translate((-lsketchLocOffset.x + sfxtrans * lrealpaperscale) * TN.CENTRELINE_MAGNIFICATION, (+lsketchLocOffset.y + sfytrans * lrealpaperscale) * TN.CENTRELINE_MAGNIFICATION); else pframesketchtrans.translate((sfxtrans * lrealpaperscale) * TN.CENTRELINE_MAGNIFICATION, (sfytrans * lrealpaperscale) * TN.CENTRELINE_MAGNIFICATION); if (sfscaledown != 0.0) pframesketchtrans.scale(lrealpaperscale / sfscaledown, lrealpaperscale / sfscaledown); if (sfrotatedeg != 0.0) pframesketchtrans.rotate(-Math.toRadians(sfrotatedeg)); if (pframesketch != null) pframesketchtrans.translate(pframesketch.sketchLocOffset.x * TN.CENTRELINE_MAGNIFICATION, -pframesketch.sketchLocOffset.y * TN.CENTRELINE_MAGNIFICATION); } ///////////////////////////////////////////// // reverse of decoding for saving void WriteXML(String areasigsketchname, LineOutputStream los, int indent) throws IOException { // the area signal los.WriteLine(TNXML.xcomopen(indent, TNXML.sPC_AREA_SIGNAL, TNXML.sAREA_PRESENT, areasigsketchname, TNXML.sASIG_FRAME_SCALEDOWN, String.valueOf(sfscaledown), TNXML.sASIG_FRAME_ROTATEDEG, String.valueOf(sfrotatedeg), TNXML.sASIG_FRAME_ELEVROTDEG, String.valueOf(sfelevrotdeg), TNXML.sASIG_FRAME_ELEVVERTPLANE, sfelevvertplane, TNXML.sASIG_FRAME_XTRANS, String.valueOf(sfxtrans), TNXML.sASIG_FRAME_YTRANS, String.valueOf(sfytrans), TNXML.sASIG_FRAME_SKETCH, sfsketch, TNXML.sASIG_FRAME_STYLE, sfstyle, TNXML.sASIG_NODECONN_ZSETRELATIVE, String.valueOf(sfnodeconnzsetrelative), TNXML.sASIG_FRAME_IMGPIXELWIDTH, String.valueOf(imagepixelswidth), TNXML.sASIG_FRAME_IMGPIXELHEIGHT, String.valueOf(imagepixelsheight))); for (String ssubset : submapping.keySet()) los.WriteLine(TNXML.xcom(indent + 1, TNXML.sSUBSET_ATTRIBUTES, TNXML.sSUBSET_NAME, ssubset, TNXML.sUPPER_SUBSET_NAME, submapping.get(ssubset))); los.WriteLine(TNXML.xcomclose(indent, TNXML.sPC_AREA_SIGNAL)); } ///////////////////////////////////////////// OnePath MakeBackgroundOutline(double lrealpaperscale, Vec3 lsketchLocOffset) { System.out.println("eeeeep"); if (pframeimage == null) return null; SetImageWidthHeight(); int biw = (imagepixelswidth == -1 ? 400 : imagepixelswidth); int bih = (imagepixelsheight == -1 ? 400 : imagepixelsheight); Point2D[] cproj = new Point2D[4]; for (int i = 0; i < 4; i++) cproj[i] = new Point2D.Double(); TransformBackiPT(0.0, 0.0, lrealpaperscale, lsketchLocOffset, cproj[0]); TransformBackiPT(biw, 0.0, lrealpaperscale, lsketchLocOffset, cproj[1]); TransformBackiPT(biw, bih, lrealpaperscale, lsketchLocOffset, cproj[2]); TransformBackiPT(0.0, bih, lrealpaperscale, lsketchLocOffset, cproj[3]); System.out.println(cproj[0].getX() + " -------------- " + cproj[0].getY()); OnePathNode opns = new OnePathNode((float)cproj[0].getX(), (float)cproj[0].getY(), 0.0F); OnePath gop = new OnePath(opns); gop.LineTo((float)cproj[1].getX(), (float)cproj[1].getY()); gop.LineTo((float)cproj[2].getX(), (float)cproj[2].getY()); gop.LineTo((float)cproj[3].getX(), (float)cproj[3].getY()); gop.EndPath(opns); gop.linestyle = SketchLineStyle.SLS_CONNECTIVE; gop.bWantSplined = false; gop.plabedl = new PathLabelDecode(); gop.plabedl.barea_pres_signal = SketchLineStyle.ASE_SKETCHFRAME; // just now need to find where it is in the list in the combo-box gop.plabedl.iarea_pres_signal = SketchLineStyle.iareasigframe; gop.plabedl.sketchframedef = new SketchFrameDef(); return gop; } ///////////////////////////////////////////// void MaxCentreOnScreenButt(Dimension lcsize, boolean bmaxcen, double lrealposterpaperscale, Vec3 lsketchLocOffset, AffineTransform ucurrtrans) { Point2D[] corners = new Point2D[4]; double lrealpaperscale = (IsImageType() ? 1.0 : lrealposterpaperscale); System.out.println("DDD " + lcsize); if (IsImageType()) { if (pframeimage != null) { SetImageWidthHeight(); int biw = (imagepixelswidth == -1 ? 400 : imagepixelswidth); int bih = (imagepixelsheight == -1 ? 400 : imagepixelsheight); corners[0] = new Point2D.Double(0.0, 0.0); corners[1] = new Point2D.Double(biw, 0.0); corners[2] = new Point2D.Double(0.0, bih); corners[3] = new Point2D.Double(biw, bih); } else { TN.emitWarning("No frame image pframeimage"); return; } } else { if (pframesketch == null) return; Rectangle2D rske; if (sfelevrotdeg == 0.0) rske = pframesketch.getBounds(false, false); else { MakeElevClines(true); if (elevclines.isEmpty()) return; rske = elevclines.get(0).gp.getBounds(); for (ElevCLine ecl : elevclines) rske.add(ecl.gp.getBounds()); } System.out.println("RSKK " + rske); corners[0] = new Point2D.Double(rske.getX(), rske.getY()); corners[1] = new Point2D.Double(rske.getX() + rske.getWidth(), rske.getY()); corners[2] = new Point2D.Double(rske.getX(), rske.getY() + rske.getHeight()); corners[3] = new Point2D.Double(rske.getX() + rske.getWidth(), rske.getY() + rske.getHeight()); } Point2D[] cproj = new Point2D[8]; for (int i = 0; i < 8; i++) cproj[i] = new Point2D.Double(); // find the scale change that would fit if (bmaxcen) { for (int i = 0; i < 4; i++) { TransformBackiPT(corners[i].getX(), corners[i].getY(), lrealpaperscale, lsketchLocOffset, cproj[i + 4]); ucurrtrans.transform(cproj[i + 4], cproj[i]); } double xmin = Math.min(Math.min(cproj[0].getX(), cproj[1].getX()), Math.min(cproj[2].getX(), cproj[3].getX())); double xmax = Math.max(Math.max(cproj[0].getX(), cproj[1].getX()), Math.max(cproj[2].getX(), cproj[3].getX())); double ymin = Math.min(Math.min(cproj[0].getY(), cproj[1].getY()), Math.min(cproj[2].getY(), cproj[3].getY())); double ymax = Math.max(Math.max(cproj[0].getY(), cproj[1].getY()), Math.max(cproj[2].getY(), cproj[3].getY())); System.out.println("XX " + xmin + " " + xmax); System.out.println("XX " + ymin + " " + xmax); double sca = Math.max((xmax - xmin) / lcsize.getWidth(), (ymax - ymin) / lcsize.getHeight()); System.out.println("XX " + ymin + " " + xmax); sfscaledown *= sca; } // centre case for (int i = 0; i < 4; i++) TransformBackiPT(corners[i].getX(), corners[i].getY(), lrealpaperscale, lsketchLocOffset, cproj[i]); double xcen = (cproj[0].getX() + cproj[1].getX() + cproj[2].getX() + cproj[3].getX()) / 4; double ycen = (cproj[0].getY() + cproj[1].getY() + cproj[2].getY() + cproj[3].getY()) / 4; try { ucurrtrans.inverseTransform(new Point2D.Double(lcsize.getWidth() / 2, lcsize.getHeight() / 2), cproj[4]); } catch (NoninvertibleTransformException e) {;}; sfxtrans += ((cproj[4].getX() - xcen) / (lrealpaperscale * TN.CENTRELINE_MAGNIFICATION)); sfytrans += ((cproj[4].getY() - ycen) / (lrealpaperscale * TN.CENTRELINE_MAGNIFICATION)); } ///////////////////////////////////////////// void SetSketchFrameFiller(MainBox mainbox, double lrealposterpaperscale, Vec3 lsketchLocOffset, FileAbstraction fasketch) { OneSketch lpframesketch = null; if (IsImageType()) { pframeimage = FileAbstraction.GetImageFile(fasketch, sfsketch); System.out.println("jdjdj " + (pframeimage != null ? pframeimage.toString() : "null")); } else { // this should worry about the sketches that have not yet been saved but exist in the box window System.out.println("MMMMMM " + fasketch + " " + sfsketch); FileAbstraction pframesketch = FileAbstraction.GetImageFile(fasketch, TN.setSuffix(sfsketch, TN.SUFF_XML)); if (pframesketch != null) lpframesketch = mainbox.FindSketchFrame(mainbox.GetActiveTunnelSketches(), pframesketch); pframeimage = null; // total chaos going on here } double lrealpaperscale = (IsImageType() ? 1.0 : lrealposterpaperscale); UpdateSketchFrame(lpframesketch, lrealpaperscale, lsketchLocOffset); } // to compare the application of TransformPT to the matrix value // get the inverse transform //make void InverseTransformBackiPT //the translation will be the difference of the two. ///////////////////////////////////////////// void TransformBackiPT(double x, double y, double lrealpaperscale, Vec3 lsketchLocOffset, Point2D res) { double cx, cy; if (IsImageType()) { cx = x; cy = y; assert lrealpaperscale == 1.0; } else { cx = x + pframesketch.sketchLocOffset.x * TN.CENTRELINE_MAGNIFICATION; cy = y - pframesketch.sketchLocOffset.y * TN.CENTRELINE_MAGNIFICATION; } double sfrotaterad = Math.toRadians(sfrotatedeg); double sinr = Math.sin(-sfrotaterad); double cosr = Math.cos(-sfrotaterad); double crx = cx * cosr - cy * sinr; double cry = cy * cosr + cx * sinr; res.setLocation(crx * lrealpaperscale / sfscaledown + sfxtrans * lrealpaperscale * TN.CENTRELINE_MAGNIFICATION - lsketchLocOffset.x * TN.CENTRELINE_MAGNIFICATION, cry * lrealpaperscale / sfscaledown + sfytrans * lrealpaperscale * TN.CENTRELINE_MAGNIFICATION + lsketchLocOffset.y * TN.CENTRELINE_MAGNIFICATION); } ///////////////////////////////////////////// void InverseTransformBackiPT(double x, double y, double lrealpaperscale, Vec3 lsketchLocOffset, Point2D res) { double crx = (x - sfxtrans * lrealpaperscale * TN.CENTRELINE_MAGNIFICATION + lsketchLocOffset.x * TN.CENTRELINE_MAGNIFICATION) * sfscaledown / lrealpaperscale; double cry = (y - sfytrans * lrealpaperscale * TN.CENTRELINE_MAGNIFICATION - lsketchLocOffset.y * TN.CENTRELINE_MAGNIFICATION) * sfscaledown / lrealpaperscale; double sfrotaterad = Math.toRadians(sfrotatedeg); double sinr = Math.sin(sfrotaterad); double cosr = Math.cos(sfrotaterad); double cx = crx * cosr - cry * sinr; double cy = cry * cosr + crx * sinr; if (IsImageType()) { res.setLocation(cx, cy); assert lrealpaperscale == 1.0; } else res.setLocation(cx - pframesketch.sketchLocOffset.x * TN.CENTRELINE_MAGNIFICATION, cy + pframesketch.sketchLocOffset.y * TN.CENTRELINE_MAGNIFICATION); } ///////////////////////////////////////////// boolean ConvertSketchTransformT(float[] pco, int nlines, double lrealposterpaperscale, Vec3 lsketchLocOffset, AffineTransform ucurrtrans, OnePath fop) { Point2D p0 = new Point2D.Double(pco[0], pco[1]); Point2D p1 = new Point2D.Double(pco[2], pco[3]); Point2D p2 = (nlines == 2 ? new Point2D.Double(pco[4], pco[5]) : null); // elevation plane, so transform points into that coordinate space if (!sfelevvertplane.equals("")) { // transform back onto the screen, then transform back to the coordinates of the elevation thing AffineTransform vptrans = MakeVertplaneTransform(ucurrtrans, fop); if (vptrans == null) return TN.emitWarning("MakeVertplaneTransform says we are edge on"); ucurrtrans.transform(p0, p0); ucurrtrans.transform(p1, p1); if (p2 != null) ucurrtrans.transform(p2, p2); try { vptrans.inverseTransform(p0, p0); vptrans.inverseTransform(p1, p1); if (p2 != null) vptrans.inverseTransform(p2, p2); } catch (NoninvertibleTransformException e) { return TN.emitWarning("Cannot invert vptrans"); }; lsketchLocOffset = new Vec3(0.0F, 0.0F, 0.0F); // zero the value as its effect has already been factored } // the flat includes (that are for frame posters) respond to paper scale, but everything else is of same scale // this should really depend on the including sketch rather than the included image double lrealpaperscale = (IsImageType() ? 1.0 : lrealposterpaperscale); if (p2 != null) { // discover the scale and rotation, and then apply them after which we translate // the to attempt to bring the fixed p0 point back to the same place on the screen Point2D ppres = new Point2D.Double(); InverseTransformBackiPT(p0.getX(), p0.getY(), lrealpaperscale, lsketchLocOffset, ppres); System.out.println("p0 " + p0 + " lsketchLocOffset="+lsketchLocOffset); System.out.println("PPres0 " + ppres); double x2 = p2.getX() - p0.getX(); double y2 = p2.getY() - p0.getY(); double x1 = p1.getX() - p0.getX(); double y1 = p1.getY() - p0.getY(); double len2 = Math.hypot(x2, y2); double len1 = Math.hypot(x1, y1); double len12 = len1 * len2; if (len12 == 0.0F) return TN.emitWarning("Cannot scale/rotate from or to zero vector"); double dot12 = (x1 * x2 + y1 * y2) / len12; double dot1p2 = (x1 * y2 - y1 * x2) / len12; double sca = len2 / len1; double ang = Math.toDegrees(Math.atan2(dot1p2, dot12)); System.out.println("AAA: " + ang + " " + sca); sfscaledown /= sca; sfrotatedeg -= ang; TransformBackiPT(ppres.getX(), ppres.getY(), lrealpaperscale, lsketchLocOffset, ppres); sfxtrans += ((p0.getX() - ppres.getX()) / (lrealpaperscale * TN.CENTRELINE_MAGNIFICATION)); sfytrans += ((p0.getY() - ppres.getY()) / (lrealpaperscale * TN.CENTRELINE_MAGNIFICATION)); InverseTransformBackiPT(p0.getX(), p0.getY(), lrealpaperscale, lsketchLocOffset, ppres); System.out.println("PPres1 " + ppres + " (should be same as PPres0)"); } else { sfxtrans += ((p1.getX() - p0.getX()) / (lrealpaperscale * TN.CENTRELINE_MAGNIFICATION)); sfytrans += ((p1.getY() - p0.getY()) / (lrealpaperscale * TN.CENTRELINE_MAGNIFICATION)); } return true; } ///////////////////////////////////////////// boolean ConvertSketchTransformTCLINE(float[] pco, double lrealpaperscale, Vec3 lsketchLocOffset, AffineTransform ucurrtrans, OnePath opcorresp) { double vx = pco[2] - pco[0]; double vy = pco[3] - pco[1]; float[] pcoc = opcorresp.GetCoords(); double vcx = pcoc[2] - pcoc[0]; double vcy = pcoc[3] - pcoc[1]; double vclen = Math.sqrt(vcx*vcx + vcy*vcy); if ((vclen == 0.0) || (vx == 0.0)) return TN.emitWarning("Cannot align vertical leg"); sfrotatedeg = (float)Math.toDegrees(Math.atan2(vcy, vcx)); sfscaledown = (float)(vclen / vx); double cx = pcoc[0] + pframesketch.sketchLocOffset.x * TN.CENTRELINE_MAGNIFICATION; double cy = pcoc[1] - pframesketch.sketchLocOffset.y * TN.CENTRELINE_MAGNIFICATION; double sfrotaterad = Math.toRadians(sfrotatedeg); double sinr = Math.sin(-sfrotaterad); double cosr = Math.cos(-sfrotaterad); double crx = cx * cosr - cy * sinr; double cry = cy * cosr + cx * sinr; sfxtrans = (pco[0] - crx * lrealpaperscale / sfscaledown + lsketchLocOffset.x * TN.CENTRELINE_MAGNIFICATION) / (lrealpaperscale * TN.CENTRELINE_MAGNIFICATION); double yh = Math.min(pco[1], pco[3]) - 1.0; sfytrans = (yh - cry * lrealpaperscale / sfscaledown - lsketchLocOffset.y * TN.CENTRELINE_MAGNIFICATION) / (lrealpaperscale * TN.CENTRELINE_MAGNIFICATION); return true; } ///////////////////////////////////////////// void ConvertTransformImportSketchWarp(OnePath opfrom, OnePath opto, double lrealposterpaperscale, Vec3 lsketchLocOffsetFrom, Vec3 lsketchLocOffsetTo) { double lrealpaperscale = (IsImageType() ? 1.0 : lrealposterpaperscale); //System.out.println("Sketchloc offs XFT " + lsketchLocOffsetFrom.x + " " + lsketchLocOffsetTo.x); System.out.println("FFFF " + opfrom.pnstart.pn + " " + opfrom.pnend.pn); System.out.println("TTTT " + opto.pnstart.pn + " " + opto.pnend.pn); // this is the final place where work needs to happen. if (!IsImageType() && (pframesketch == null)) { TN.emitWarning("Nothing on this frame type"); return; } Point2D ppgoF = new Point2D.Double(); Point2D ppgoF0 = new Point2D.Double(); TransformBackiPT(opfrom.pnstart.pn.getX(), opfrom.pnstart.pn.getY(), lrealpaperscale, lsketchLocOffsetFrom, ppgoF); TransformBackiPT(0.0, 0.0, lrealpaperscale, lsketchLocOffsetFrom, ppgoF0); double fvx = ppgoF0.getX() - opfrom.pnstart.pn.getX(); double fvy = ppgoF0.getY() - opfrom.pnstart.pn.getY(); //System.out.println("PPres0 " + ppgoF); double x1 = opfrom.pnend.pn.getX() - opfrom.pnstart.pn.getX(); double y1 = opfrom.pnend.pn.getY() - opfrom.pnstart.pn.getY(); double x2 = opto.pnend.pn.getX() - opto.pnstart.pn.getX(); double y2 = opto.pnend.pn.getY() - opto.pnstart.pn.getY(); if ((x1 == 0.0) && (y1 == 0.0)) { float[] pcof = opfrom.GetCoords(); x1 = pcof[2] - opfrom.pnstart.pn.getX(); y1 = pcof[3] - opfrom.pnstart.pn.getY(); float[] pcot = opto.GetCoords(); x2 = pcot[2] - opto.pnstart.pn.getX(); y2 = pcot[3] - opto.pnstart.pn.getY(); } double len2 = Math.hypot(x2, y2); double len1 = Math.hypot(x1, y1); double len12 = len1 * len2; if (len12 != 0.0F) { double dot12 = (x1 * x2 + y1 * y2) / len12; double dot1p2 = (x1 * y2 - y1 * x2) / len12; double sca = len2 / len1; double ang = Math.toDegrees(Math.atan2(dot1p2, dot12)); //System.out.println("A-AAA: " + ang + " " + sca); sfscaledown /= sca; sfrotatedeg -= ang; } else TN.emitWarning("need to pick a better pair of points"); // double cosang = Math.cos(ang); // double sinang = Math.sin(ang); Point2D ppgoT = new Point2D.Double(); Point2D ppgoT0 = new Point2D.Double(); TransformBackiPT(opto.pnstart.pn.getX(), opto.pnstart.pn.getY(), lrealpaperscale, lsketchLocOffsetTo, ppgoT); TransformBackiPT(0.0, 0.0, lrealpaperscale, lsketchLocOffsetTo, ppgoT0); // double rfvx = (fvx * cosang - fvy * sinang) * sca; // double rfvy = (fvy * cosang + fvx * sinang) * sca; double rfvx = fvx; double rfvy = fvy; //System.out.println(" rrrfv " + rfvx + " " + rfvy); //T + (F - F0) // sfxtrans += (float)((ppgoF.getX() - ppgoT0.getX()) / (lrealpaperscale * TN.CENTRELINE_MAGNIFICATION)); // sfytrans += (float)((ppgoF.getY() - ppgoT0.getY()) / (lrealpaperscale * TN.CENTRELINE_MAGNIFICATION)); sfxtrans += ((rfvx + opto.pnstart.pn.getX() - ppgoT0.getX()) / (lrealpaperscale * TN.CENTRELINE_MAGNIFICATION)); sfytrans += ((rfvy + opto.pnstart.pn.getY() - ppgoT0.getY()) / (lrealpaperscale * TN.CENTRELINE_MAGNIFICATION)); // sfxtrans += (float)(-lsketchLocOffsetFrom.x + lsketchLocOffsetTo.x); // sfytrans += (float)(-lsketchLocOffsetFrom.y + lsketchLocOffsetTo.y); // sfxtrans += (float)((opfrom.pnstart.pn.getX() - opto.pnstart.pn.getX()) / TN.CENTRELINE_MAGNIFICATION); // sfytrans += (float)((opfrom.pnstart.pn.getY() - opto.pnstart.pn.getY()) / TN.CENTRELINE_MAGNIFICATION); //System.out.println("PPresT " + ppgoT); TransformBackiPT(0, 0, lrealpaperscale, lsketchLocOffsetTo, ppgoT); //System.out.println(" NNN PPresT " + ppgoT); //System.out.println("XXX " + (opfrom.pnstart.pn.getX() - opto.pnstart.pn.getX())); //System.out.println(" YYY " + (opfrom.pnstart.pn.getY() - opto.pnstart.pn.getY())); } ///////////////////////////////////////////// /* boolean MakeElevClinesUnfold() { Stack statrec = new Stack(); for (OnePath op : pframesketch.vpaths) { if (op.linestyle != SketchLineStyle.SLS_CENTRELINE) continue; elevclines = new ArrayList(); elevclines.add(new ElevCLine(op, pframesketch.sketchLocOffset, coselevrot, sinelevrot)); TN.emitWarning("making station calculations for a disconnected component of the survey at station "+ol.osfrom); ol.osfrom.Loc = new Vec3((float)npieces * 1000.0F, 0.0F, 0.0F); statrec.push(ol.osfrom); nstationsdone++; npieces++; CalcPosStack(); } } */ ///////////////////////////////////////////// boolean MakeElevClines(boolean bcentrelineonly) { elevclines = new ArrayList(); // if (sfelevvertplane.equals("extunfold")) // return MakeElevClinesUnroll(); double elevrotrad = Math.toRadians(sfelevrotdeg); double coselevrot = Math.cos(elevrotrad); double sinelevrot = Math.sin(elevrotrad); for (OnePath op : pframesketch.vpaths) { if ((bcentrelineonly ? (op.linestyle == SketchLineStyle.SLS_CENTRELINE) : !((op.linestyle == SketchLineStyle.SLS_INVISIBLE) || (op.linestyle == SketchLineStyle.SLS_CONNECTIVE))) && (op.pnstart != null)) elevclines.add(new ElevCLine(op, pframesketch.sketchLocOffset, coselevrot, sinelevrot)); } Collections.sort(elevclines); TN.emitMessage("Made " + elevclines.size() + " elecvlines"); return true; } ///////////////////////////////////////////// // centreline elevation mode void paintWelevSketch(GraphicsAbstraction ga, SubsetAttrStyle sksas, boolean bcentrelineonly) { if (sfelevvertplane.equals("extunfold")) System.out.println("Here's where we unfold!!!!!!!!"); MakeElevClines(bcentrelineonly); for (ElevCLine ecl : elevclines) { String ssubset = ecl.csubset; String lssubset = submapping.get(ssubset); if ((lssubset != null) && !lssubset.equals("")) ssubset = lssubset; SubsetAttr subsetattr = sksas.msubsets.get(ssubset); if (subsetattr == null) subsetattr = sksas.sadefault; subsetattr = ecl.subsetattr; if (subsetattr.linestyleattrs[ecl.linestyle].strokecolour != null) ga.drawShape(ecl.gp, subsetattr.linestyleattrs[ecl.linestyle]); } } } tunnelx-20140102.orig/src/PocketTopoLoader.java0000644000000000000000000003153612261213471016146 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2009 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.io.IOException; import java.io.FileNotFoundException; import java.util.Arrays; import java.util.List; import java.util.ArrayList; import java.util.Stack; import java.util.Collections; import java.util.Collection; import java.util.Map; import java.util.HashMap; import java.util.Set; import java.util.HashSet; ///////////////////////////////////////////// // This is of the .txt files. For loading the binary .top files // look at TunnelTopParser.java ///////////////////////////////////////////// class PocketTopoLoader { ///////////////////////////////////////////// int[] splaycounters = new int[512]; StringBuilder sbsvx = new StringBuilder(); StringBuilder sbsvxsplay = new StringBuilder(); List vpathsplan = new ArrayList(); ///////////////////////////////////////////// //FIX //1.0 0.000 0.000 0.000 void LoadFix(LineInputStream lis) throws IOException { assert (lis.GetLine().equals("FIX")); lis.FetchNextLine(); //1.0 0.000 0.000 0.000 assert lis.w[0].startsWith("1."); sbsvx.append("*fix\t" + lis.w[0].substring(2) + "\t" + lis.w[1] + "\t" + lis.w[2] + "\t" + lis.w[3] + TN.nl); lis.FetchNextLine(); } ///////////////////////////////////////////// //TRIP //DATE 2009-04-20 //DECLINATION 0.00 //DATA void LoadTrip(LineInputStream lis) throws IOException { assert (lis.GetLine().equals("TRIP")); lis.FetchNextLine(); assert lis.w[0].equals("DATE"); sbsvx.append("*date\t" + lis.w[1].replace("-", ".") + TN.nl); lis.FetchNextLine(); assert lis.w[0].equals("DECLINATION"); sbsvx.append("*calibrate\tdeclination\t" + lis.w[1] + TN.nl); lis.FetchNextLine(); assert lis.GetLine().equals("DATA"); lis.FetchNextLine(); } ///////////////////////////////////////////// static OnePathNode NewCentrelineNode(String stationlabel, String sx, String sy, float xdisp) { String sxy = sx+","+sy; float x = Float.valueOf(sx) * TN.CENTRELINE_MAGNIFICATION + xdisp; float y = -Float.valueOf(sy) * TN.CENTRELINE_MAGNIFICATION; OnePathNode opn = new OnePathNode(x, y, 0.0F); opn.pnstationlabel = stationlabel + " ".substring(stationlabel.length()) + sx+","+sy; return opn; } ///////////////////////////////////////////// static OnePathNode FindStationNode(String sx, String sy, List stationnodes, int iss, float xdisp) { String sxy = sx+","+sy; assert ((iss == 0) || (iss == 10)); for (OnePathNode opn : stationnodes) { if (sxy.equals(opn.pnstationlabel.substring(iss))) return opn; } // no new nodes in case of the station if (iss == 10) return null; // make new node in case of the sketch float x = Float.valueOf(sx) * TN.CENTRELINE_MAGNIFICATION + xdisp; float y = -Float.valueOf(sy) * TN.CENTRELINE_MAGNIFICATION; OnePathNode opn = new OnePathNode(x, y, 0.0F); opn.pnstationlabel = sxy; return opn; } ///////////////////////////////////////////// void LoadTopoSketch(LineInputStream lis, List vpaths, float xdisp) throws IOException { System.out.println("Loadingplan"); lis.FetchNextLine(); assert (lis.GetLine().equals("STATIONS")); List stationnodes = new ArrayList(); while (lis.FetchNextLine()) { if (lis.GetLine().equals("SHOTS")) break; assert (lis.iwc == 3); assert lis.w[2].startsWith("1."); stationnodes.add(NewCentrelineNode(lis.w[2].substring(2), lis.w[0], lis.w[1], xdisp)); } List splaynodes = new ArrayList(); assert (lis.GetLine().equals("SHOTS")); int splaycount = 1; while (lis.FetchNextLine()) { if (lis.GetLine().startsWith("POLYLINE")) break; if (lis.GetLine().startsWith("ELEVATION")) break; if (lis.iwc == 0) continue; if (lis.iwc != 4) lis.emitError("SHOTS line does not have 4 terms"); OnePathNode lpnstart = FindStationNode(lis.w[0], lis.w[1], stationnodes, 10, xdisp); OnePathNode lpnend = FindStationNode(lis.w[2], lis.w[3], stationnodes, 10, xdisp); // centreline type if ((lpnstart != null) && (lpnend != null)) // not splay type vpaths.add(new OnePath(lpnstart, lpnstart.pnstationlabel.substring(0, 10).trim(), lpnend, lpnend.pnstationlabel.substring(0, 10).trim())); // build the splay type (sigh) else if ((lpnstart != null) || (lpnend != null)) { if (lpnstart == null) { lpnstart = NewCentrelineNode(String.valueOf(splaycount++), lis.w[0], lis.w[1], xdisp); splaynodes.add(lpnstart); } if (lpnend == null) { lpnend = NewCentrelineNode(String.valueOf(splaycount++), lis.w[2], lis.w[3], xdisp); splaynodes.add(lpnend); } vpaths.add(new OnePath(lpnstart, lpnstart.pnstationlabel.substring(0, 10).trim(), lpnend, lpnend.pnstationlabel.substring(0, 10).trim())); } else lis.emitWarning("Unable to find stations for shot endpoints"); } for (OnePathNode opn : stationnodes) opn.pnstationlabel = null; for (OnePathNode opn : splaynodes) opn.pnstationlabel = null; // the sketch List vnodes = new ArrayList(); if (lis.GetLine().startsWith("ELEVATION")) return; // missing shots section assert (lis.GetLine().startsWith("POLYLINE")); while (true) { if (lis.iwc == 0) break; assert (lis.iwc == 2); assert (lis.w[0].equals("POLYLINE")); String col = lis.w[1]; OnePathNode opnstart = null; OnePath op = null; String sx = null; String sy = null; while (lis.FetchNextLine()) { if ((lis.iwc != 2) || lis.w[0].equals("POLYLINE")) break; sx = lis.w[0]; sy = lis.w[1]; if (opnstart == null) { opnstart = FindStationNode(lis.w[0], lis.w[1], vnodes, 0, xdisp); op = new OnePath(opnstart); } else { float x = Float.valueOf(sx) * TN.CENTRELINE_MAGNIFICATION + xdisp; float y = -Float.valueOf(sy) * TN.CENTRELINE_MAGNIFICATION; op.LineTo(x, y); } } // case of single point if (op.nlines == 0) { sy = String.valueOf(Float.valueOf(sy) + 0.06F); float x = Float.valueOf(sx) * TN.CENTRELINE_MAGNIFICATION + xdisp; float y = -Float.valueOf(sy) * TN.CENTRELINE_MAGNIFICATION; op.LineTo(x, y); } OnePathNode opnend = FindStationNode(sx, sy, vnodes, 0, xdisp); op.EndPath(opnend); if (col.equals("CONNECT")) op.linestyle = SketchLineStyle.SLS_CONNECTIVE; else if (col.equals("BROWN")) { op.linestyle = SketchLineStyle.SLS_DETAIL; op.vssubsets.add("orange"); } else if (col.equals("BLACK")) op.linestyle = SketchLineStyle.SLS_WALL; else if (col.equals("RED")) { op.linestyle = SketchLineStyle.SLS_DETAIL; op.vssubsets.add("red"); } else if (col.equals("GRAY")) { op.linestyle = SketchLineStyle.SLS_DETAIL; op.vssubsets.add("strongrey"); } else if (col.equals("BLUE")) { op.linestyle = SketchLineStyle.SLS_DETAIL; op.vssubsets.add("blue"); } else if (col.equals("GREEN")) { op.linestyle = SketchLineStyle.SLS_DETAIL; op.vssubsets.add("green"); } else { op.linestyle = SketchLineStyle.SLS_CEILINGBOUND; System.out.println("Unknown topocolo: " + col); } vpaths.add(op); } } ///////////////////////////////////////////// void LoadSVXData(LineInputStream lis) throws IOException { lis.FetchNextLine(); if (lis.GetLine().equals("FIX")) LoadFix(lis); assert lis.GetLine().equals("TRIP"); // the trip group is at the start, but sometimes there's one halfway through (eg to set the date) lis.UnFetch(); while (lis.FetchNextLine()) { if (lis.GetLine().equals("TRIP")) LoadTrip(lis); // quit when we have a blank line if (lis.iwc == 0) break; assert !lis.w[0].equals("PLAN"); // 1.19 1.18 351.68 -26.98 6.404 > assert lis.w[0].startsWith("1."); if (lis.iwc == 6) { assert lis.w[1].startsWith("1."); // < > indicate the direction on the extended elevation assert lis.w[5].equals(">") || lis.w[5].equals("<"); sbsvx.append(lis.w[0].substring(2) + "\t" + lis.w[1].substring(2) + "\t" + lis.w[4] + "\t" + lis.w[2] + "\t" + lis.w[3] + TN.nl); } else if (lis.iwc == 5) { assert lis.w[4].equals(">") || lis.w[4].equals("<"); String splaystation = lis.w[0].substring(2); int isplaystation = Integer.valueOf(splaystation); splaycounters[isplaystation]++; sbsvxsplay.append(splaystation); sbsvxsplay.append("\t"); sbsvxsplay.append(splaystation); sbsvxsplay.append("_"); sbsvxsplay.append(splaycounters[isplaystation]); sbsvxsplay.append("\t"); sbsvxsplay.append(lis.w[3] + "\t" + lis.w[1] + "\t" + lis.w[2] + TN.nl); } else assert false; // unknown string format } } ///////////////////////////////////////////// void LoadPockettopo(FileAbstraction loadfile) { try { LineInputStream lis = new LineInputStream(loadfile.GetInputStream(), loadfile, null, null); LoadSVXData(lis); lis.FetchNextLine(); if (lis.GetLine().equals("PLAN")) LoadTopoSketch(lis, vpathsplan, 0.0F); lis.FetchNextLine(); if (lis.GetLine().equals("ELEVATION")) LoadTopoSketch(lis, vpathsplan, 1000.F); if (!lis.FetchNextLine()) { TN.emitWarning("Unaccounted lines"); lis.UnFetch(); while (lis.FetchNextLine()) System.out.println("Unnacounted line: " + lis.GetLine()); } lis.inputstream.close(); } catch (IOException e) { TN.emitError(e.toString()); }; } ///////////////////////////////////////////// String GetSVX() { return sbsvx.toString() + TN.nl + "*flags splay" + TN.nl + sbsvxsplay.toString() + TN.nl; } ///////////////////////////////////////////// static boolean IsPocketTopo(String sfilehead) { if (sfilehead.indexOf("FIX") == 0) return true; if (sfilehead.indexOf("TRIP") == 0) return true; return false; } } tunnelx-20140102.orig/src/WireframeGraphics.java0000644000000000000000000003311111762432750016331 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import javax.swing.JPanel; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Dimension; import java.awt.Image; import java.awt.Color; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.event.MouseEvent; import java.awt.event.ActionEvent; import java.util.List; import java.util.ArrayList; import java.util.SortedSet; import java.util.TreeSet; // // // WireframeGraphics // // class WireframeGraphics extends JPanel implements MouseListener, MouseMotionListener { WireframeDisplay wireframedisplay; DepthCol depthcol = new DepthCol(); List vstations = new ArrayList(); List vlegs = new ArrayList(); boolean bEditable = false; // recordings of active objects OneStation vstationactive = null; OneStation vstationactivesel = null; // current rotation Matrix3D mat = new Matrix3D(); Matrix3D invmat = new Matrix3D(); // main centre offset Vec3 coff = new Vec3(); // quaternion rotations Quaternion qnow = new Quaternion(); Quaternion qmdown = new Quaternion(); Quaternion qmdrag = new Quaternion(); Vec3 vmdown = new Vec3(); Vec3 vmdrag = new Vec3(); // Zfixed rotations float zfRotZ = (float)Math.PI / 2; float zfRotX = (float)Math.PI / 2; float zfRotZdown = 0.0F; float zfRotXdown = 0.0F; int tcmx; // mouse coordinates used for dragging the tube cone int tcmy; Matrix3D rotmat = new Matrix3D(); Matrix3D invrotmat = new Matrix3D(); float diameter = 20.0F; Dimension csize = new Dimension(0, 0); int xoc = 0; int yoc = 0; // values used by the dynamic rotate and scale // old and new offsets Vec3 ocoff = new Vec3(); Vec3 ncoff = new Vec3(); float xfac; int prevx = 0; int prevy = 0; float prevdiameter = 0.0F; // screen vectors Vec3 sxvec = new Vec3(); Vec3 syvec = new Vec3(); Vec3 szvec = new Vec3(); // the axes WireAxes wireaxes = new WireAxes(); // mouse motion state final static int M_NONE = 0; final static int M_DYN_ROTATE = 1; final static int M_DYN_TRANSLATE = 2; final static int M_DYN_SCALE = 3; final static int M_SEL_STATIONS = 4; int momotion = M_NONE; // types of repainting boolean bNeedsClearing = false; boolean bNeedsRedrawing = false; //(maybe only redrawing a little piece of the pic) ///////////////////////////////////////////// WireframeGraphics(WireframeDisplay lwireframedisplay) { super(true); // doublebuffered setBackground(TN.skeBackground); setForeground(TN.wfmLeg); addMouseListener(this); addMouseMotionListener(this); wireframedisplay = lwireframedisplay; } ///////////////////////////////////////////// void UpdateDepthCol() { for (int i = 0; i < vstations.size(); i++) { OneStation os = vstations.get(i); depthcol.AbsorbRange(os, (i == 0)); } SortedSet legdates = new TreeSet(); for (OneLeg ol : vlegs) legdates.add(ol.svxdate); depthcol.svxdates.clear(); depthcol.svxdates.addAll(legdates); depthcol.datelimit = (depthcol.svxdates.isEmpty() ? "" : depthcol.svxdates.get(depthcol.svxdates.size() - 1)); } ///////////////////////////////////////////// public void paintComponent(Graphics g) { // test if resize has happened if ((getSize().height != csize.height) || (getSize().width != csize.width)) ReformView(); setBackground(TN.wfmBackground); /* if (bNeedsClearing) { g.clearRect(0, 0, csize.width, csize.height); bNeedsClearing = false; } else if (!bNeedsRedrawing) return; bNeedsRedrawing = false; */ //g.clearRect(0, 0, csize.width, csize.height); g.setColor(TN.wfmBackground); g.fillRect(0, 0, csize.width, csize.height); // draw the legs if (wireframedisplay.miCentreline.isSelected()) { for (OneLeg ol : vlegs) { if (ol.osfrom != null) { ol.paintW(g, !bEditable, (wireframedisplay.miDepthCols.isSelected() ? depthcol : null)); } } } // draw the stations if (wireframedisplay.miStationNames.isSelected() && !((momotion == M_DYN_ROTATE) || (momotion == M_DYN_TRANSLATE) || (momotion == M_DYN_SCALE))) { for (OneStation os : vstations) if (os != vstationactive) os.paintW(g, false, false); } if (vstationactive != null) vstationactive.paintW(g, true, !bEditable); // draw the axes if (wireframedisplay.miAxes.isSelected()) wireaxes.paintW(g); } ///////////////////////////////////////////// void ReformMatrix() { // first reform the matrix csize.width = getSize().width; csize.height = getSize().height; // first calculate the scale int minwidth = Math.min(csize.width, csize.height); if (minwidth == 0) minwidth = 1; xfac = minwidth / diameter; // centre of screen xoc = csize.width / 2; yoc = csize.height / 2; mat.unit(); mat.translate(coff.x, coff.y, coff.z); rotmat.SetQuat(qnow.x, qnow.y, qnow.z, qnow.w); mat.mult(rotmat); mat.scale(xfac, -xfac, xfac); mat.translate(xoc, yoc, 0); sxvec.SetXYZ(rotmat.xx, rotmat.xy, rotmat.xz); syvec.SetXYZ(rotmat.yx, rotmat.yy, rotmat.yz); szvec.SetXYZ(rotmat.zx, rotmat.zy, rotmat.zz); // inverse matrix invmat.unit(); invmat.translate(-xoc, -yoc, 0); invmat.scale(1.0F / xfac, 1.0F / (-xfac), 1.0F / xfac); invrotmat.SetQuat(qnow.x, qnow.y, qnow.z, -qnow.w); invmat.mult(invrotmat); invmat.translate(-coff.x, -coff.y, -coff.z); } ///////////////////////////////////////////// void ReformView() { bNeedsClearing = true; ReformMatrix(); // axes position wireaxes.ReformAxes(rotmat, csize, xoc, yoc, xfac); // now transform the stations and points of the XSections for (OneStation os : vstations) os.SetTLoc(mat); } ///////////////////////////////////////////// ///////////////////////////////////////////// ///////////////////////////////////////////// ///////////////////////////////////////////// void ReCentre(int mx, int my) { // find centre depth int izlo = 0; int izhi = -1; for (OneStation os : vstations) { // scan only the stations that are on the screen // (ignores legs, unfortunately). Could make this a menu switch. if ((os.TLocX > -10) && (os.TLocX < csize.width + 10) && (os.TLocY > -10) && (os.TLocY < csize.height + 10)) { int iz = os.TLocZ; if ((izhi == -1) && (izlo == 0)) { izlo = iz; izhi = iz; } else { if (iz < izlo) izlo = iz; if (iz > izhi) izhi = iz; } } } int mz = (izlo + izhi) / 2; ncoff.x = -(mx * invmat.xx + my * invmat.xy + mz * invmat.xz + invmat.xo); ncoff.y = -(mx * invmat.yx + my * invmat.yy + mz * invmat.yz + invmat.yo); ncoff.z = -(mx * invmat.zx + my * invmat.zy + mz * invmat.zz + invmat.zo); ReformView(); } ///////////////////////////////////////////// ///////////////////////////////////////////// void MaximizeView() { // probably this ought to be calculating directly from the point // positions without using the ReformView information. if (vstations.isEmpty()) return; float fxlo = 0.0F; float fxhi = 0.0F; float fylo = 0.0F; float fyhi = 0.0F; boolean bfirst = true; for (OneStation os : vstations) { float fx = sxvec.Dot(os.Loc); float fy = syvec.Dot(os.Loc); if (bfirst || (fx < fxlo)) fxlo = fx; if (bfirst || (fx > fxhi)) fxhi = fx; if (bfirst || (fy < fylo)) fylo = fy; if (bfirst || (fy > fyhi)) fyhi = fy; bfirst = false; } // do the centring float fcx = -(fxhi + fxlo) / 2; float fcy = -(fyhi + fylo) / 2; coff.SetXYZ(fcx * sxvec.x + fcy * syvec.x, fcx * sxvec.y + fcy * syvec.y, fcx * sxvec.z + fcy * syvec.z); // do the scaling float fxd = Math.max(fxhi - fxlo, 0.1F); float fyd = Math.max(fyhi - fylo, 0.1F); diameter = ((csize.width / fxd < csize.height / fyd) ? fxd : fyd) * 1.2F; } ///////////////////////////////////////////// void CalcQView() { float LzfRotX = zfRotX - ((int)(zfRotX / (float)Math.PI) + (zfRotX < 0.0F ? -1 : 0)) * (float)Math.PI; float LzfRotZ = zfRotZ - ((int)(zfRotZ / (float)Math.PI) + (zfRotZ < 0.0F ? -1 : 0)) * (float)Math.PI; qmdown.SetXYZ(0.0F, 0.0F, (float)Math.cos(LzfRotX)); qmdrag.SetXYZ(-(float)Math.cos(LzfRotZ), 0.0F, 0.0F); qnow.Mult(qmdown, qmdrag); } ///////////////////////////////////////////// public void SetAutomaticView(float lzfRotX, float lzfRotZ) { if (lzfRotX != -1.0) { zfRotX = lzfRotX; zfRotZ = lzfRotZ; CalcQView(); } else MaximizeView(); ReformView(); repaint(); } ///////////////////////////////////////////// // mouse events ///////////////////////////////////////////// ///////////////////////////////////////////// public void mouseMoved(MouseEvent e) {;} public void mouseClicked(MouseEvent e) {;} public void mouseEntered(MouseEvent e) {;}; public void mouseExited(MouseEvent e) {;}; ///////////////////////////////////////////// public void mousePressed(MouseEvent e) { // if a point is already being dragged, then this second mouse press will delete it. if (momotion != M_NONE) { vstationactive = null; momotion = M_NONE; repaint(); return; } int x = e.getX(); int y = e.getY(); // selection types (right mouse) if (e.isMetaDown()) { momotion = M_SEL_STATIONS; if (!bEditable && (momotion != M_SEL_STATIONS)) momotion = M_NONE; } // select the motion type (left mouse) else { if (e.isShiftDown()) momotion = M_DYN_TRANSLATE; else if (e.isControlDown()) momotion = M_DYN_SCALE; else momotion = M_DYN_ROTATE; } // act on the motion type switch(momotion) { case M_DYN_SCALE: case M_DYN_TRANSLATE: ReCentre(x, y); ocoff.SetXYZ(coff.x, coff.y, coff.z); prevx = x; prevy = y; prevdiameter = diameter; break; case M_DYN_ROTATE: ReCentre(xoc, yoc); coff.SetXYZ(ncoff.x, ncoff.y, ncoff.z); prevx = x; prevy = y; if (!wireframedisplay.miZFixed.isSelected()) { vmdown.SetOnSphere((float)(x - xoc) * 2 / csize.width, -(float)(y - yoc) * 2 / csize.height); qmdown.SetFrom(qnow); } else { zfRotXdown = zfRotX; zfRotZdown = zfRotZ; } break; case M_SEL_STATIONS: { vstationactivesel = null; int rdistsq = TN.XSinteractiveSensitivitySQ; for (OneStation vstation : vstations) { int idistsq = vstation.sqDist(x, y); if (idistsq < rdistsq) { rdistsq = idistsq; vstationactivesel = vstation; } } vstationactive = vstationactivesel; if (vstationactive != null) repaint(); else momotion = M_NONE; } break; default: break; } } ///////////////////////////////////////////// public void mouseDragged(MouseEvent e) { int x = e.getX(); int y = e.getY(); // act on the motion type float lambda; switch(momotion) { case M_DYN_ROTATE: if (!wireframedisplay.miZFixed.isSelected()) { vmdrag.SetOnSphere((float)(x - xoc) * 2 / csize.width, -(float)(y - yoc) * 2 / csize.height); qmdrag.VecRot(vmdown, vmdrag); qnow.Mult(qmdown, qmdrag); } else { zfRotX = zfRotXdown + (float)Math.PI * (x - prevx) / csize.width; zfRotZ = zfRotZdown + (float)Math.PI * (y - prevy) / csize.height; CalcQView(); } ReformView(); repaint(); break; case M_DYN_SCALE: lambda = 1.0F + ((float)Math.abs(x - prevx) / csize.width) * 2.0F; if (x > prevx) lambda = 1.0F / lambda; diameter = prevdiameter * lambda; coff.SetAlong(lambda, ncoff, ocoff); ReformView(); repaint(); break; case M_DYN_TRANSLATE: { float lx = (x - prevx) / xfac; float ly = -(y - prevy) / xfac; coff.SetXYZ(ocoff.x + lx * sxvec.x + ly * syvec.x, ocoff.y + lx * sxvec.y + ly * syvec.y, ocoff.z + lx * sxvec.z + ly * syvec.z); ReformView(); repaint(); } break; case M_SEL_STATIONS: { OneStation vsaOld = vstationactive; vstationactive = ((vstationactivesel.sqDist(x, y) < TN.XSinteractiveSensitivitySQ) ? vstationactivesel : null); if (vstationactive != vsaOld) { bNeedsRedrawing = true; repaint(); } } break; case M_NONE: break; default: break; } } ///////////////////////////////////////////// public void mouseReleased(MouseEvent e) { int x = e.getX(); int y = e.getY(); switch(momotion) { case M_SEL_STATIONS: vstationactivesel = null; vstationactive = null; break; case M_DYN_ROTATE: case M_DYN_SCALE: case M_DYN_TRANSLATE: break; case M_NONE: return; default: break; } momotion = M_NONE; bNeedsRedrawing = true; repaint(); // get the labels back. } } tunnelx-20140102.orig/src/SubsetAttrStyle.java0000644000000000000000000002721011762432750016053 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2004 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.BasicStroke; import java.awt.Font; import java.awt.Color; import java.util.List; import java.util.ArrayList; import java.util.Map; import java.util.HashMap; import java.util.Collections; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreePath; import javax.swing.tree.TreeNode; ///////////////////////////////////////////// // enables us to display the frameref subsets in brackets without disrupting its value class DefaultMutableTreeNodeSBrack extends DefaultMutableTreeNode { String sbrack; DefaultMutableTreeNodeSBrack(String s) { super(s); sbrack = "(" + s + ")"; } public String toString() { return sbrack; } } ///////////////////////////////////////////// class SubsetAttrStyle implements Comparable { String stylename; boolean bselectable; // whether we show up in the dropdown list (or is this a partial String shortstylename; // used in the dropdown box int iloadorder; // used for sorting the order of loading, so we can put them in the drop-down box correctly; since using a map loses this ordering Map msubsets = new HashMap(); Map msubsetdm = new HashMap(); // constructed in MakeTreeRootNode, helps find the nodes to tag on framedef subsets SubsetAttr sadefault = null; //for (Map.Entry e : m.entrySet()) //System.out.println(e.getKey() + ": " + e.getValue()); DefaultMutableTreeNode dmroot = new DefaultMutableTreeNode("root"); DefaultTreeModel dmtreemod = new DefaultTreeModel(dmroot); List unattributedss = new ArrayList(); // contains the same, but as SubsetAttrs DefaultMutableTreeNode dmunattributess = new DefaultMutableTreeNode("_Unattributed_"); SortedSet datess = new TreeSet(); // __date__ type subsets for easier block selections DefaultMutableTreeNode dmdatess = new DefaultMutableTreeNode("_Dates_"); List xsectionss = new ArrayList(); // those that appear superficially to act as subsets (they contain a centreline of elevation type) DefaultMutableTreeNode dmxsectionss = new DefaultMutableTreeNode("_XSections_"); List framerefss = new ArrayList(); // those listed in submapping of a sketchframedef but not in the sketch DefaultMutableTreeNode dmxframerefss = new DefaultMutableTreeNode("_Framerefs_"); TreePath tpxsection = (new TreePath(dmroot)).pathByAddingChild(dmxsectionss); List framedefsubnodes = new ArrayList(); SketchGrid sketchgrid = null; ///////////////////////////////////////////// public int compareTo(SubsetAttrStyle sas) { return iloadorder - sas.iloadorder; } ///////////////////////////////////////////// void MakeTreeRootNode() { dmroot.removeAllChildren(); List dmtnarr = new ArrayList(); msubsetdm.clear(); // build the tree downwards from each primary root node for (SubsetAttr sa : msubsets.values()) { if (sa.uppersubsetattr != null) continue; DefaultMutableTreeNode cnode = new DefaultMutableTreeNode(sa); dmroot.add(cnode); dmtnarr.add(cnode); msubsetdm.put(sa.subsetname, cnode); while (!dmtnarr.isEmpty()) { DefaultMutableTreeNode lcnode = dmtnarr.remove(dmtnarr.size() - 1); SubsetAttr lsa = (SubsetAttr)lcnode.getUserObject(); for (SubsetAttr dsa : lsa.subsetsdownmap.values()) { DefaultMutableTreeNode ncnode = new DefaultMutableTreeNode(dsa); lcnode.add(ncnode); // the tree msubsetdm.put(dsa.subsetname, ncnode); dmtnarr.add(ncnode); // the stack } } } // this is a separate dynamic folder with the subsets that don't have any subset attributes on them dmroot.add(dmunattributess); dmroot.add(dmdatess); dmroot.add(dmxsectionss); dmroot.add(dmxframerefss); dmtreemod.reload(dmroot); } ///////////////////////////////////////////// void TreeListUnattributedSubsets(List vpaths) { unattributedss.clear(); datess.clear(); xsectionss.clear(); framerefss.clear(); for (OnePath op : vpaths) { for (String ssubset : op.vssubsets) { if (msubsets.containsKey(ssubset)) continue; if (ssubset.startsWith("__date__ ")) { datess.add(ssubset); continue; } if ((op.linestyle == SketchLineStyle.SLS_CENTRELINE) && (op.plabedl != null) && (op.plabedl.centrelineelev != null) && op.plabedl.centrelineelev.equals(ssubset) && !xsectionss.contains(ssubset)) xsectionss.add(ssubset); if (!unattributedss.contains(ssubset)) unattributedss.add(ssubset); } if ((op.plabedl != null) && (op.plabedl.barea_pres_signal == SketchLineStyle.ASE_SKETCHFRAME)) { for (String mess : op.plabedl.sketchframedef.submapping.keySet()) { if (!mess.equals("") && !framerefss.contains(mess)) framerefss.add(mess); } } } dmunattributess.removeAllChildren(); dmdatess.removeAllChildren(); dmxsectionss.removeAllChildren(); dmxframerefss.removeAllChildren(); Collections.reverse(xsectionss); Collections.reverse(framerefss); Collections.sort(unattributedss); for (String ssubset : xsectionss) dmxsectionss.add(new DefaultMutableTreeNode(ssubset)); for (String ssubset : unattributedss) { if (!xsectionss.contains(ssubset)) dmunattributess.add(new DefaultMutableTreeNode(ssubset)); } for (String ssubset : datess) { dmdatess.add(new DefaultMutableTreeNode(ssubset)); } for (String ssubset : framerefss) { if (!xsectionss.contains(ssubset) && !unattributedss.contains(ssubset)) dmxframerefss.add(new DefaultMutableTreeNode(ssubset)); } dmtreemod.reload(dmunattributess); dmtreemod.reload(dmdatess); dmtreemod.reload(dmxsectionss); dmtreemod.reload(dmxframerefss); } ///////////////////////////////////////////// void TreeListFrameDefCopiedSubsets(SketchFrameDef sketchframedefCopied) { // now add in any new submapping for (DefaultMutableTreeNode dmfss : framedefsubnodes) { TreeNode dmfssp = dmfss.getParent(); dmfss.removeFromParent(); if (dmfssp != null) dmtreemod.reload(dmfssp); } framedefsubnodes.clear(); for (Map.Entry mess : sketchframedefCopied.submapping.entrySet()) { if (mess.getValue().equals("") || mess.getKey().equals("")) continue; DefaultMutableTreeNode dmtupper = msubsetdm.get(mess.getValue()); if (dmtupper != null) { System.out.println(" fnd: " + mess.getValue() + " " + mess.getKey()); DefaultMutableTreeNode dmtlower = new DefaultMutableTreeNodeSBrack(mess.getKey()); dmtupper.add(dmtlower); framedefsubnodes.add(dmtlower); dmtreemod.reload(dmtupper); } } } ///////////////////////////////////////////// SubsetAttrStyle(String lstylename, int liloadorder, boolean lbselectable) { stylename = lstylename; iloadorder = liloadorder; if (stylename.length() > 15) shortstylename = stylename.substring(0, 9) + "--" + stylename.substring(stylename.length() - 3); else shortstylename = stylename; bselectable = lbselectable; //System.out.println(" creating " + stylename + (bselectable ? " (selectable)" : "") + " shortname " + shortstylename); } ///////////////////////////////////////////// // these settings will be used to set a second layer of invisibility (entirely hide -- not just grey out -- from the list anything that is in any of these bViewhidden subsets. void ToggleViewHidden(Set vsselectedsubsets, boolean btransitive) { List sarecurse = new ArrayList(); for (String ssubsetname : vsselectedsubsets) sarecurse.add(msubsets.get(ssubsetname)); while (!sarecurse.isEmpty()) { SubsetAttr sa = sarecurse.remove(sarecurse.size() - 1); if (sa == null) continue; sa.bViewhidden = !sa.bViewhidden; if (!btransitive) continue; for (SubsetAttr dsa : sa.subsetsdownmap.values()) sarecurse.add(dsa); } dmtreemod.reload(dmroot); // should call nodesChanged on the individual ones (tricky because of no pointers to TreeNodes), but keep it simple for now } ///////////////////////////////////////////// // used for the combobox which needs a short name // it would be nice if I could put tooltips public String toString() { return shortstylename; } ///////////////////////////////////////////// void ImportSubsetAttrStyle(SubsetAttrStyle lsas) // does a huge copy of a batch of subsetattributestyles { for (SubsetAttr lsa : lsas.msubsets.values()) { SubsetAttr nsa = new SubsetAttr(lsa); //subsets.add(nsa); msubsets.put(lsa.subsetname, nsa); } if (lsas.sketchgrid != null) sketchgrid = lsas.sketchgrid; // copy down from above } ///////////////////////////////////////////// void AssignDefault(SketchFrameDef sketchframedef) { sadefault = null; if (sketchframedef != null) { String ldefault = sketchframedef.submapping.get("default"); if ((ldefault != null) && !ldefault.equals("")) sadefault = msubsets.get(ldefault); } if (sadefault == null) { sadefault = msubsets.get("default"); if (sadefault == null) TN.emitWarning("Missing default on style: " + stylename); } } ///////////////////////////////////////////// // the variables don't work well because the upper subsets don't get copied into the // lower subsets and then evaluated. Only if they are referenced do they get duplicated // and then have their variable evaluated in the lower level void FillAllMissingAttributes() { for (SubsetAttr sa : msubsets.values()) sa.subsetsdownmap.clear(); //System.out.println("Updating::" + stylename); // set pointers up for (SubsetAttr sa : msubsets.values()) { if (sa.uppersubset != null) { sa.uppersubsetattr = msubsets.get(sa.uppersubset); if (sa.uppersubsetattr != null) { assert !sa.uppersubsetattr.subsetsdownmap.containsKey(sa.subsetname); sa.uppersubsetattr.subsetsdownmap.put(sa.subsetname, sa); } else if (bselectable) TN.emitWarning("Upper subset " + sa.uppersubset + " not found of " + sa.subsetname + " in style: " + stylename); } } // make the tree in reverse order of definition (or could have set up a partial sort) // used to evaluate it in order List subsetsrevdef = new ArrayList(); for (SubsetAttr sa : msubsets.values()) { if (sa.uppersubset == null) SelectedSubsetStructure.VRecurseSubsetsdown(subsetsrevdef, sa); } // recurse over missing attributes for each subset for (SubsetAttr sa : subsetsrevdef) sa.FillMissingAttribs(); // get this part done MakeTreeRootNode(); } }; tunnelx-20140102.orig/src/ImageWarp.java0000644000000000000000000001501612261213471014577 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import javax.swing.JPanel; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JTextField; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Color; import java.io.IOException; import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; import java.awt.geom.NoninvertibleTransformException; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.Image; import java.awt.image.BufferedImage; import javax.imageio.ImageIO; //////////////////////////////////////////////////////////////////////////////// class ImageWarp { // this is the background image FileAbstraction lbackimageF = null; // if these differ then we need to update FileAbstraction backimageF = null; BufferedImage backimage = null; boolean bBackImageGood = true; // this is the image that it renders into in the panel Dimension csize; BufferedImage backimagedone; Graphics2D backimagedoneGraphics; boolean bBackImageDoneGood = false; // needs update. JPanel foreground; SketchGraphics sketchgraphicspanel; boolean bMaxBackImage = false; AffineTransform currtrans = new AffineTransform(); AffineTransform currparttrans = new AffineTransform(); ///////////////////////////////////////////// void PreConcatBusiness(AffineTransform mdtrans) { currparttrans.preConcatenate(mdtrans); } ///////////////////////////////////////////// ImageWarp(Dimension lcsize, JPanel lforeground) { csize = lcsize; foreground = lforeground; } ///////////////////////////////////////////// void SketchBackground(AffineTransform ucurrtrans) { if (backimageF == null ? (lbackimageF != null) : !backimageF.equals(lbackimageF)) { backimageF = lbackimageF; backimage = null; if (backimageF != null) backimage = backimageF.GetImage(false); } // make the transformed image for the view window Dimension lcsize = foreground.getSize(); if ((backimagedone == null) || (backimagedone.getWidth() != lcsize.width) || (backimagedone.getHeight() != lcsize.height)) { backimagedone = new BufferedImage(lcsize.width, lcsize.height, BufferedImage.TYPE_INT_RGB); backimagedoneGraphics = (Graphics2D)backimagedone.getGraphics(); TN.emitMessage("new backimagedone"); } backimagedoneGraphics.setColor(SketchLineStyle.blankbackimagecol); backimagedoneGraphics.fillRect(0, 0, backimagedone.getWidth(), backimagedone.getHeight()); // the frame image types -- which will replace the old style OnePath fop = sketchgraphicspanel.tsketch.opframebackgrounddrag; if ((fop != null) && (fop.plabedl != null) && (fop.plabedl.sketchframedef != null) && ((fop.plabedl.sketchframedef.pframeimage != null) || (fop.plabedl.sketchframedef.pframesketch != null))) { // could potentially trim it SketchFrameDef sketchframedef = fop.plabedl.sketchframedef; SubsetAttrStyle sksas = null; if (sketchframedef.pframesketch != null) { // calculate the state of mapping we should have in the frame sketch and compare it sksas = sketchgraphicspanel.sketchdisplay.sketchlinestyle.subsetattrstylesmap.get(sketchframedef.sfstyle); if (sksas == null) sksas = sketchgraphicspanel.sketchdisplay.sketchlinestyle.subsetattrstylesmap.get("default"); if ((sksas != null) && ((sksas != sketchframedef.pframesketch.sksascurrent) || !sketchframedef.pframesketch.submappingcurrent.equals(sketchframedef.submapping))) { // problem occurs when importing from same sketch into background (say, for elevation) the style gets messed up because there is only one style on the sketch at a time TN.emitMessage("-- Resetting sketchstyle to Frame thing " + sksas.stylename + " during ImageWarp"); int scchangetyp = sketchframedef.pframesketch.SetSubsetAttrStyle(sksas, sketchframedef); SketchGraphics.SketchChangedStatic(scchangetyp, sketchframedef.pframesketch, null); assert (sksas == sketchframedef.pframesketch.sksascurrent); // if iproper == SketchGraphics.SC_UPDATE_ALL (not SketchGraphics.SC_UPDATE_ALL_BUT_SYMBOLS) // then it could do it as through a window so that not the whole thing needs redoing. sketchframedef.pframesketch.UpdateSomething(SketchGraphics.SC_UPDATE_ALL_BUT_SYMBOLS, false); SketchGraphics.SketchChangedStatic(SketchGraphics.SC_UPDATE_ALL_BUT_SYMBOLS, sketchframedef.pframesketch, null); } } AffineTransform satrans = backimagedoneGraphics.getTransform(); GraphicsAbstraction ga = new GraphicsAbstraction(backimagedoneGraphics); currtrans = sketchframedef.MakeVertplaneTransform(ucurrtrans, fop); // identity if normal plane if (currtrans != null) // if not an edge on case { currtrans.concatenate(sketchframedef.pframesketchtrans); ga.transform(currtrans); if (sketchframedef.pframeimage != null) ga.drawImage(sketchframedef.SetImageWidthHeight()); else if ((sketchframedef.sfelevrotdeg == 0.0) && !sketchframedef.sfelevvertplane.equals("extunfold")) sketchframedef.pframesketch.paintWqualitySketch(ga, Math.max(2, sketchgraphicspanel.sketchdisplay.printingpanel.cbRenderingQuality.getSelectedIndex()), null); else sketchframedef.paintWelevSketch(ga, sksas, false); } // draw the controlling path in orange backimagedoneGraphics.setTransform(ucurrtrans); ga.drawPath(sketchgraphicspanel.tsketch.opframebackgrounddrag, SketchLineStyle.framebackgrounddragstyleattr); backimagedoneGraphics.setTransform(satrans); return; // bail out now we've done the new back image } if (backimage == null) return; TN.emitWarning("Shouldn't get here - dead backgroundimage code"); } } tunnelx-20140102.orig/src/SqliteInterface.java0000644000000000000000000001441512261213471016007 0ustar package Tunnel; import java.util.List; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.Statement; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; public class SqliteInterface { Connection conn; SqliteInterface(String path) { try { Class.forName("org.sqlite.JDBC"); conn = DriverManager.getConnection("jdbc:sqlite:"+path); } catch (java.sql.SQLException e) {System.out.println(e);} catch (java.lang.ClassNotFoundException e) {System.out.println(e);} } void CreateTables() { try { Statement stat = conn.createStatement(); stat.executeUpdate("drop table if exists paths;"); String pathfields = "pathid integer unique, linestyle text, d text, bsplined boolean, "+ "pathidtailleft integer, btailleftfore boolean, "+ "pathidheadright integer, bheadrightfore boolean, "+ "zalttail real, zalthead real"; stat.executeUpdate("create table paths ("+pathfields+");"); // centreline node names and zalt values in separate table? // also need to insert locx and locy into this scheme // then some calculated tables of symbol layouts and connected components stat.executeUpdate("drop table if exists pathsymbols;"); stat.executeUpdate("create table pathsymbols (pathid integer, labsymb text);"); stat.executeUpdate("drop table if exists pathlabels;"); String pathlabelfields = "pathid integer, sfontcode text, drawlab text, fnodeposxrel real, fnodeposyrel real, barrowpresent boolean, bboxpresent boolean"; stat.executeUpdate("create table pathlabels ("+pathlabelfields+");"); stat.executeUpdate("drop table if exists pathareasignals;"); stat.executeUpdate("create table pathareasignals (pathid integer, areasignal text, zsetrelative real);"); stat.executeUpdate("drop table if exists sketchframes;"); String sketchframefields = "pathid integer, sfsketch text, scaledown real, rotatedeg real, xtrans real, ytrans real, submapping text, style text, imagepixelswidth integer, imagepixelsheight integer"; stat.executeUpdate("create table sketchframes ("+sketchframefields+");"); } catch (java.sql.SQLException e) {System.out.println(e);} } void WritePaths(List vpaths) { try { for (int i = 0; i < vpaths.size(); i++) vpaths.get(i).svgid = i; PreparedStatement preppath = conn.prepareStatement("insert into paths values (?,?,?,?,?, ?,?,?,?,?);"); PreparedStatement preppathsymbol = conn.prepareStatement("insert into pathsymbols values (?,?);"); PreparedStatement preppathlabel = conn.prepareStatement("insert into pathlabels values (?,?,?,?,?, ?,?);"); PreparedStatement preppathareasignal = conn.prepareStatement("insert into pathareasignals values (?,?,?);"); PreparedStatement prepsketchframe = conn.prepareStatement("insert into sketchframes values (?,?,?,?,?, ?,?,?,?,?);"); for (OnePath op : vpaths) { preppath.setInt(1, op.svgid); preppath.setString(2, SketchLineStyle.shortlinestylenames[op.linestyle]); preppath.setString(3, "NOOOOO"); //op.svgdvalue(0.0F, 0.0F)); preppath.setBoolean(4, op.bSplined); preppath.setInt(5, (op.aptailleft == null ? op.aptailleft.svgid : -1)); preppath.setBoolean(6, op.baptlfore); preppath.setInt(7, (op.apforeright == null ? op.apforeright.svgid : -1)); preppath.setBoolean(8, op.bapfrfore); preppath.setFloat(9, op.pnstart.zalt); preppath.setFloat(10, op.pnend.zalt); preppath.addBatch(); if (op.plabedl == null) continue; for (String labsymb : op.plabedl.vlabsymb) { preppathsymbol.setInt(1, op.svgid); preppathsymbol.setString(2, labsymb); preppathsymbol.addBatch(); } if (!op.plabedl.sfontcode.equals("")) { preppathlabel.setInt(1, op.svgid); preppathlabel.setString(2, op.plabedl.sfontcode); preppathlabel.setString(3, op.plabedl.drawlab); preppathlabel.setFloat(4, op.plabedl.fnodeposxrel); preppathlabel.setFloat(5, op.plabedl.fnodeposyrel); preppathlabel.setBoolean(6, op.plabedl.barrowpresent); preppathlabel.setBoolean(7, op.plabedl.bboxpresent); preppathlabel.addBatch(); } if (op.plabedl.iarea_pres_signal != 0) { preppathareasignal.setInt(1, op.svgid); preppathareasignal.setString(2, SketchLineStyle.areasignames[op.plabedl.iarea_pres_signal]); preppathareasignal.setFloat(3, op.plabedl.nodeconnzsetrelative); preppathareasignal.addBatch(); } if (op.plabedl.barea_pres_signal == SketchLineStyle.ASE_SKETCHFRAME) { prepsketchframe.setInt(1, op.svgid); prepsketchframe.setString(2, op.plabedl.sketchframedef.sfsketch); prepsketchframe.setFloat(3, op.plabedl.sketchframedef.sfscaledown); prepsketchframe.setFloat(4, op.plabedl.sketchframedef.sfrotatedeg); prepsketchframe.setDouble(5, op.plabedl.sketchframedef.sfxtrans); prepsketchframe.setDouble(6, op.plabedl.sketchframedef.sfytrans); // Map submapping = new TreeMap(); prepsketchframe.setString(7, "notset"); prepsketchframe.setString(8, op.plabedl.sketchframedef.sfstyle); prepsketchframe.setInt(9, op.plabedl.sketchframedef.imagepixelswidth); prepsketchframe.setInt(10, op.plabedl.sketchframedef.imagepixelsheight); prepsketchframe.addBatch(); } } conn.setAutoCommit(false); preppath.executeBatch(); preppathsymbol.executeBatch(); preppathlabel.executeBatch(); preppathareasignal.executeBatch(); prepsketchframe.executeBatch(); conn.setAutoCommit(true); } catch (java.sql.SQLException e) {System.out.println(e);} } }tunnelx-20140102.orig/src/SketchInfoPanel.java0000644000000000000000000003300512261213471015736 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2004 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import javax.swing.JPanel; import javax.swing.JButton; import javax.swing.JRadioButton; import javax.swing.ButtonGroup; import javax.swing.JTextField; import javax.swing.JTextArea; import javax.swing.JLabel; import javax.swing.JScrollPane; import java.awt.event.MouseListener; import java.awt.event.MouseEvent; import java.awt.event.MouseAdapter; import javax.swing.JList; import javax.swing.ListModel; import javax.swing.DefaultListModel; import javax.swing.ListSelectionModel; import javax.swing.event.ListSelectionListener; import javax.swing.event.ListSelectionEvent; import javax.swing.JLabel; import javax.swing.ListCellRenderer; import java.awt.Component; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.CardLayout; import java.awt.Insets; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.awt.geom.Point2D; import java.awt.Color; import java.util.regex.Matcher; ///////////////////////////////////////////// class SketchInfoPanel extends JPanel { SketchDisplay sketchdisplay; JTextField tfmousex = new JTextField(); JTextField tfmousey = new JTextField(); JTextField tfdistance = new JTextField(); JTextField tfbearing = new JTextField(); JTextArea tapathxml = new JTextArea(""); LineOutputStream lospathxml = new LineOutputStream(); boolean bsuppresssetpathinfo = false; JButton buttaddfix = new JButton("New nodes"); JButton buttsearch = new JButton("Search"); JTextField tfenterfield = new JTextField(); CardLayout vcardlayout = new CardLayout(); JPanel pancards = new JPanel(vcardlayout); DefaultListModel searchlistmodel; ; JList searchlist; // this doesn't appear to give me a monospaced font anyway dammit! Font monofont = new Font(Font.MONOSPACED, Font.PLAIN, 12); Color listcolor = new Color(240, 255, 240); ///////////////////////////////////////////// SketchInfoPanel(SketchDisplay lsketchdisplay) { //Font[] fs = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts(); //for (int i = 0; i < fs.length; i++) // System.out.println(fs[i].toString()); sketchdisplay = lsketchdisplay; buttaddfix.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { AddFixPath(); } } ); buttaddfix.setToolTipText("Convert a comma separated list of coordinates to a path"); buttsearch.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { SearchLabels(); } } ); buttsearch.setToolTipText("Search for labels in sketch"); tfenterfield.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { SearchLabels(); } } ); tapathxml.setFont(monofont); tapathxml.setEditable(false); tfmousex.setEditable(false); tfmousey.setEditable(false); tfdistance.setEditable(false); tfbearing.setEditable(false); Insets inset = new Insets(1, 1, 1, 1); buttaddfix.setMargin(inset); buttsearch.setMargin(inset); // selpathxml card pancards.add(new JScrollPane(tapathxml), "selpathxml"); // searchopt card searchlistmodel = new DefaultListModel(); searchlist = new JList(searchlistmodel); searchlist.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); searchlist.setCellRenderer(new SearchCellRenderer()); searchlist.setBackground(listcolor); searchlist.addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { if (!e.getValueIsAdjusting() && (searchlist.getSelectedIndex() != -1)) { Object o = searchlistmodel.getElementAt(searchlist.getSelectedIndex()); OnePath op = (OnePath)o; bsuppresssetpathinfo = true; sketchdisplay.sketchgraphicspanel.SelectSingle(op); bsuppresssetpathinfo = false; } } }); searchlist.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) sketchdisplay.sketchgraphicspanel.MaxAction(122); } }); JPanel pan1 = new JPanel(new GridLayout(1, 2)); pan1.add(buttaddfix); pan1.add(buttsearch); JPanel pan3 = new JPanel(new GridLayout(2, 1)); pan3.add(tfenterfield); pan3.add(pan1); JPanel pansearch = new JPanel(new BorderLayout()); pansearch.add(new JScrollPane(searchlist), BorderLayout.CENTER); pansearch.add(pan3, BorderLayout.SOUTH); pancards.add(pansearch, "searchopt"); // bottom part JPanel pan2 = new JPanel(new GridLayout(2, 4)); pan2.add(new JLabel("X:", JLabel.RIGHT)); pan2.add(tfmousex); pan2.add(new JLabel("Y:", JLabel.RIGHT)); pan2.add(tfmousey); pan2.add(new JLabel("Dist:", JLabel.RIGHT)); pan2.add(tfdistance); pan2.add(new JLabel("Bearing:", JLabel.RIGHT)); pan2.add(tfbearing); // main pane layout setLayout(new BorderLayout()); add(pancards, BorderLayout.CENTER); add(pan2, BorderLayout.SOUTH); } ///////////////////////////////////////////// void AddFixPath() { System.out.println("Hi there:" + tfenterfield.getText()); String[] nums = tfenterfield.getText().split("[\\s,]+"); try { for (int i = 1; i < nums.length; i += 2) { float lfixedx = Float.parseFloat(nums[i - 1]); float fixedx = TN.CENTRELINE_MAGNIFICATION * (lfixedx - sketchdisplay.sketchgraphicspanel.tsketch.sketchLocOffset.x); float lfixedy = Float.parseFloat(nums[i]); float fixedy = -TN.CENTRELINE_MAGNIFICATION * (lfixedy - sketchdisplay.sketchgraphicspanel.tsketch.sketchLocOffset.y); if (sketchdisplay.sketchgraphicspanel.bmoulinactive) { sketchdisplay.sketchgraphicspanel.currgenpath.LineTo(fixedx, fixedy); sketchdisplay.sketchgraphicspanel.SetMouseLine(new Point2D.Float(fixedx, fixedy), sketchdisplay.sketchgraphicspanel.moupt); } else { OnePathNode fixedpt = new OnePathNode(fixedx, fixedy, 0); fixedpt.SetNodeCloseBefore(sketchdisplay.sketchgraphicspanel.tsketch.vnodes, sketchdisplay.sketchgraphicspanel.tsketch.vnodes.size()); sketchdisplay.sketchgraphicspanel.StartCurve(fixedpt); } } } catch (NumberFormatException e) {;} sketchdisplay.sketchgraphicspanel.repaint(); /* String[] bits = coords.split(" "); Float fixedx = new Float(bits[0]); Float fixedy = new Float(bits[1]); System.out.println("Fixing endpath at " + coords); OnePathNode fixedpt = new OnePathNode(10*fixedx-10*tsketch.sketchLocOffset.x,-10*fixedy+10*tsketch.sketchLocOffset.y,0); // sic! the mixed signs are confusing, and I only got that by trial and error :-) if(!bmoulinactive) { ClearSelection(true); fixedpt.SetNodeCloseBefore(tsketch.vnodes, tsketch.vnodes.size()); StartCurve(fixedpt); } else { EndCurve(fixedpt); } */ } ///////////////////////////////////////////// void SetSketchInfo(OneSketch tsketch) { vcardlayout.show(pancards, "selpathxml"); tapathxml.setText(""); tapathxml.append("tunnelproject (at load) = "+tsketch.tunnelprojectloaded+"\n"); tapathxml.append("tunneluser (at load) = "+tsketch.tunneluserloaded+"\n"); tapathxml.append("tunnelversion (at load) = "+tsketch.tunnelversionloaded+"\n"); tapathxml.append("tunneldate (at load) = "+tsketch.tunneldateloaded+"\n"); tapathxml.append("#nodes = "+tsketch.vnodes.size()+"\n"); tapathxml.append("#paths = "+tsketch.vpaths.size()+"\n"); tapathxml.append("sketchLocOffset = "+tsketch.sketchLocOffset.toString()+"\n"); tapathxml.append("realposterpaperscale = "+tsketch.realposterpaperscale+"\n"); } ///////////////////////////////////////////// void SetPathXML(OnePath op, Vec3 sketchLocOffset) { if (bsuppresssetpathinfo) // quick and dirty way of keeping the list panel visible return; vcardlayout.show(pancards, "selpathxml"); try { op.WriteXMLpath(lospathxml, 0, 0, 0); lospathxml.WriteLine(""); if (op.pnstart != null) op.pnstart.DumpNodeInfo(lospathxml, "start", sketchLocOffset); if (op.pnend != null) op.pnend.DumpNodeInfo(lospathxml, "end", sketchLocOffset); lospathxml.WriteLine("ciHasrendered=" + op.ciHasrendered); if (op.plabedl != null) lospathxml.WriteLine("symbc " + op.plabedl.vlabsymb.size() + "<" + op.vpsymbols.size()); lospathxml.WriteLine("kaleft: " + (op.kaleft != null ? op.kaleft.zalt + sketchLocOffset.z : "null")); lospathxml.WriteLine("karight: " + (op.karight != null ? op.karight.zalt + sketchLocOffset.z : "null")); int iselpath = sketchdisplay.sketchgraphicspanel.tsketch.vpaths.indexOf(op); // slow; (maybe not necessary) lospathxml.WriteLine("Path " + (iselpath+1) + " out of " + String.valueOf(sketchdisplay.sketchgraphicspanel.tsketch.vpaths.size())); // make shortest path case (inefficiently) ProximityDerivation pd = new ProximityDerivation(sketchdisplay.sketchgraphicspanel.tsketch); OnePathNode[] cennodes = new OnePathNode[1]; pd.ShortestPathsToCentrelineNodes(op.pnend, cennodes, null); if (cennodes[0] != null) lospathxml.WriteLine("Near station:\n " + cennodes[0].pnstationlabel); tapathxml.setText(lospathxml.sb.toString().replaceAll("\t", " ")); lospathxml.sb.setLength(0); } catch (IOException e) {;} } ///////////////////////////////////////////// void SetAreaInfo(OneSArea osa, OneSketch tsketch) { vcardlayout.show(pancards, "selpathxml"); tapathxml.setText(""); tapathxml.append("Area zalt = "); tapathxml.append(String.valueOf(osa.zalt)); tapathxml.append("\n\n"); for (OnePath op : osa.connpathrootscen) { if (op.linestyle == SketchLineStyle.SLS_CENTRELINE) tapathxml.append("connpathrootscen " + op.toStringCentreline() + "\n"); } tapathxml.append("\n"); for (ConnectiveComponentAreas cca : osa.ccalist) tapathxml.append("cca vconncomindex=" + tsketch.sksya.vconncom.indexOf(cca) + " vconnpaths=" + cca.vconnpaths.size() + "\n"); tapathxml.append("\n"); int iselarea = 0; // tsketch.vsareas.indexOf(osa) doesn't exist for (OneSArea losa : sketchdisplay.sketchgraphicspanel.tsketch.vsareas) { if (losa == osa) break; iselarea++; } tapathxml.append("Area " + (iselarea+1) + " out of " + String.valueOf(sketchdisplay.sketchgraphicspanel.tsketch.vsareas.size())); } ///////////////////////////////////////////// void SetCleared() { vcardlayout.show(pancards, "searchopt"); tapathxml.setText(""); } ///////////////////////////////////////////// void SearchLabels() { String stext = tfenterfield.getText(); if ((stext.length() != 0) && (stext.charAt(0) != '^')) { stext = stext.replaceAll("([(\\[.?{+\\\\])", "\\\\$1"); stext = stext.replaceAll("\\*", ".*?"); stext = stext.replaceAll("\\s+", "\\\\s+"); stext = ".*?" + stext + ".*?"; stext = "(?si)" + stext; } TN.emitMessage("Searching: " + stext); searchlistmodel = new DefaultListModel(); // make a new one (seems no better way to copy in whole batch) for (OnePath op : sketchdisplay.sketchgraphicspanel.tsketch.vpaths) { if ((op.plabedl != null) && !op.plabedl.drawlab.equals("")) { if ((stext.length() == 0) || op.plabedl.drawlab.matches(stext) || op.plabedl.sfontcode.matches(stext)) searchlistmodel.addElement(op); } } searchlist.setModel(searchlistmodel); } ///////////////////////////////////////////// class SearchCellRenderer extends JLabel implements ListCellRenderer { public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { if (value instanceof OnePath) { OnePath op = (OnePath)value; setText(op.plabedl.sfontcode + " ".substring(0, 11 - Math.min(10, op.plabedl.sfontcode.length())) + (op.plabedl.drawlab.length() < 20 ? op.plabedl.drawlab : op.plabedl.drawlab.substring(0, 17) + "...")); } else setText("--" + index); setForeground(isSelected ? list.getSelectionForeground() : list.getForeground()); setBackground(isSelected ? list.getSelectionBackground() : list.getBackground()); setFont(monofont); setOpaque(true); return this; } } } tunnelx-20140102.orig/src/MutualComponentArea.java0000644000000000000000000004506211762432750016662 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2007 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; // sanwang 10sec on load 15 at z, 67Mb // 23sec 110Mb at Updateareas // 12:27mins 404Mb // with SSymbSing removed // 21sec 112Mb at Updateareas // 13:11mins 153Mb import java.awt.geom.GeneralPath; import java.awt.geom.Area; import java.awt.Rectangle; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.util.ArrayList; import java.util.SortedSet; import java.util.Set; import java.util.TreeSet; import java.util.List; import java.util.ArrayList; ///////////////////////////////////////////// // single symbol (temporary), and used as an element in the boxsetting class TSSymbSing { OneSSymbol oss = null; Area atranscliparea = null; AffineTransform paxistrans = null; // maybe not necessary int splaceindex; // not used Rectangle2D abounds = null; int xilo, xihi; int yilo, yihi; boolean bxyouter; // set when we overlap beyond the set of boxes int ivisited = 0; TSSymbSing(OneSSymbol loss) { oss = loss; } void Setpaxistrans(AffineTransform lpaxistrans) { paxistrans = lpaxistrans; if (oss.ssb.gsym.cliparea != null) { atranscliparea = (Area)oss.ssb.gsym.cliparea.aarea.clone(); atranscliparea.transform(paxistrans); } } } //////////////////////////////////////////////////////////////////////////////// // this might even be the object that runs in a separate thread and itself goes through the list of MutualComponentAreas class MutualComponentAreaScratch { List latticesymbols = new ArrayList(); List othersymbols = new ArrayList(); List othersymbol = new ArrayList(); // used as an array of one // handles the lattices and axes of symbols List sscratcharr = new ArrayList(); boolean bmorethanoneconnectedcomponent; // for laying out mixtures of mud and sand. // could also use to weight the random selection int[] iactivesymbols = new int[200]; GeneralPath[] lgpsympss = new GeneralPath[200]; // this is the basic list List tssymbinterf = new ArrayList(); // boxing will be done with a matrix of matrices which we stack up List< List > boxarray = new ArrayList< List >(); List< List > sparecells = new ArrayList< List >(); int[] cellsused = new int[5000]; int ncellsused = 0; double boxxlo, boxxhi; int boxix; double boxylo, boxyhi; int boxiy; int boxn; static double boxeps = 0.0001; int Givisited = 1; ///////////////////////////////////////////// List GetBoxCell(int ix, int iy) { int iin = (ix != -1 ? ix * boxiy + iy : boxn); if (boxarray.get(iin) == null) { if (!sparecells.isEmpty()) boxarray.set(iin, sparecells.remove(sparecells.size() - 1)); else boxarray.set(iin, new ArrayList()); if (ncellsused < cellsused.length) cellsused[ncellsused++] = iin; } return boxarray.get(iin); } ///////////////////////////////////////////// void FreeBoxCells() { if (ncellsused < cellsused.length) { while (ncellsused != 0) { int iin = cellsused[--ncellsused]; boxarray.get(iin).clear(); sparecells.add(boxarray.get(iin)); boxarray.set(iin, null); } } else { for (int iin = 0; iin < boxarray.size(); iin++) { if (boxarray.get(iin) != null) { boxarray.get(iin).clear(); sparecells.add(boxarray.get(iin)); boxarray.set(iin, null); } ncellsused = 0; } } tssymbinterf.clear(); } ///////////////////////////////////////////// void BuildBoxset(Rectangle2D mbounds, double cellwidth) { if (mbounds == null) { boxix = 0; boxn = 0; return; } boxxlo = mbounds.getX(); boxxhi = boxxlo + mbounds.getWidth(); boxylo = mbounds.getY(); boxyhi = boxylo + mbounds.getHeight(); if (cellwidth == 0.0) cellwidth = (boxxhi - boxxlo) / 10.0; boxix = Math.min((int)((boxxhi - boxxlo) / cellwidth) + 2, 100); boxiy = Math.min((int)((boxyhi - boxylo) / cellwidth) + 2, 100); //System.out.println("box xx " + boxxlo + ",, " + boxxhi + " " + boxix + "-" + boxiy); boxn = boxix * boxiy; // ensure size while (boxarray.size() <= boxn) boxarray.add(null); Givisited = 1; } ///////////////////////////////////////////// static int IBox(double boxwlo, double boxwhi, int boxiw, double w) { int res = (int)((w - boxwlo) / (boxwhi - boxwlo) * boxiw); return (res < 0 ? 0 : (res >= boxiw ? boxiw - 1 : res)); } ///////////////////////////////////////////// void SetBoxRangeOnSymbol(TSSymbSing tssing) { tssing.abounds = tssing.atranscliparea.getBounds2D(); double xlo = tssing.abounds.getX() - boxeps; double xhi = tssing.abounds.getX() + tssing.abounds.getWidth() + boxeps; double ylo = tssing.abounds.getY() - boxeps; double yhi = tssing.abounds.getY() + tssing.abounds.getHeight() + boxeps; tssing.bxyouter = ((xlo < boxxlo) || (xhi > boxxhi) || (ylo < boxylo) || (yhi > boxyhi)); tssing.xilo = IBox(boxxlo, boxxhi, boxix, xlo); tssing.xihi = IBox(boxxlo, boxxhi, boxix, xhi); tssing.yilo = IBox(boxylo, boxyhi, boxiy, ylo); tssing.yihi = IBox(boxylo, boxyhi, boxiy, yhi); //System.out.print("BoxiiiI " + tssing.xilo + "|" + tssing.xihi + " " + tssing.yilo + "|" + tssing.yihi); } ///////////////////////////////////////////// void AddInterfToBoxset(TSSymbSing tssing) { tssymbinterf.add(tssing); if (tssing.bxyouter) GetBoxCell(-1, -1).add(tssing); for (int ix = tssing.xilo; ix <= tssing.xihi; ix++) for (int iy = tssing.yilo; iy <= tssing.yihi; iy++) GetBoxCell(ix, iy).add(tssing); } ///////////////////////////////////////////// boolean CheckJOverlaps(TSSymbSing jssing, TSSymbSing tssing, Area awork) { if (jssing.ivisited == Givisited) return false; jssing.ivisited = Givisited; if (jssing.atranscliparea == null) return false; //TN.emitMessage("No overlap possible between: " + tssing.oss.ssb.gsymname + " and " + jssing.oss.ssb.gsymname); if (bmorethanoneconnectedcomponent && !tssing.oss.op.pthcca.overlapcomp.contains(jssing.oss.op.pthcca)) return false; if (!tssing.abounds.intersects(jssing.abounds.getX(), jssing.abounds.getY(), jssing.abounds.getWidth(), jssing.abounds.getHeight())) return false; // intersect the two areas to see if it's non-zero awork.add(tssing.atranscliparea); awork.intersect(jssing.atranscliparea); if (!awork.isEmpty()) return true; return false; } ///////////////////////////////////////////// boolean CheckJOverlapsArr(List jssingarr, TSSymbSing tssing, Area awork) { for (TSSymbSing jssing : jssingarr) { if (CheckJOverlaps(jssing, tssing, awork)) return true; } return false; } ///////////////////////////////////////////// // the intersecting checking bit. boolean IsSymbolsPositionValid(TSSymbSing tssing) { SetBoxRangeOnSymbol(tssing); Area lsaarea = tssing.oss.op.pthcca.saarea; SSymbolBase ssb = tssing.oss.ssb; Area awork = new Area(); // first check if the symbol is in the area if it's supposed to be if (!ssb.bAllowedOutsideArea) { awork.add(tssing.atranscliparea); awork.subtract(lsaarea); if (!awork.isEmpty()) return false; // the area goes outside. } // but if symbol entirely outside, no point in having it here. else if (ssb.bTrimByArea) { awork.add(tssing.atranscliparea); awork.intersect(lsaarea); if (awork.isEmpty()) return false; awork.reset(); } if (ssb.bSymbolinterferencedoesntmatter) // although other symbols might care if they overlap this one return true; Givisited++; // this is doing the check without boxing //if (CheckJOverlapsArr(tssymbinterf, tssing, awork)) // return false; /*for (TSSymbSing jssing : tssymbinterf) { if (CheckJOverlaps(jssing, tssing, awork)) return false; }*/ // this is with boxing if (tssing.bxyouter && CheckJOverlapsArr(GetBoxCell(-1, -1), tssing, awork)) return false; for (int ix = tssing.xilo; ix <= tssing.xihi; ix++) for (int iy = tssing.yilo; iy <= tssing.yihi; iy++) { if (CheckJOverlapsArr(GetBoxCell(ix, iy), tssing, awork)) return false; } return true; } ///////////////////////////////////////////// // majority of code is for pullback in a line, but also copes with the case where no pulling happens. TSSymbSing MRelaySymbolT(OneSSymbol oss, SSymbScratch sscratch) { sscratch.placeindex++; SSymbolBase ssb = oss.ssb; TSSymbSing tssinglam1 = new TSSymbSing(oss); // make transformed location for lam0. double lam1 = (ssb.bPushout ? 2.0 : 1.0); // goes out twice as far. tssinglam1.Setpaxistrans(sscratch.BuildAxisTransT(lam1)); // case of no clipping area associated to the symbol. if (ssb.gsym.cliparea == null) return tssinglam1; boolean lam1valid = IsSymbolsPositionValid(tssinglam1); // no pullback case if ((!ssb.bPullback && !ssb.bPushout) || (sscratch.pleng * 2 <= ssb.pulltolerance)) return (lam1valid ? tssinglam1 : null); sscratch.placeindex++; // this is a pull/push type. record where we are going towards (the push-out direction). double lam0 = (ssb.bPullback ? 0.0 : 1.0); //Area lam1atranscliparea = tssing.atranscliparea; //AffineTransform lam1axistrans = tssing.paxistrans; TSSymbSing tssinglam0 = new TSSymbSing(oss); tssinglam0.Setpaxistrans(sscratch.BuildAxisTransT(lam0)); boolean lam0valid = IsSymbolsPositionValid(tssinglam0); // quick return case where we've immediately found a spot. if (lam0valid) return tssinglam0; //AffineTransform lam0axistrans = tssing.paxistrans; //Area lam0atranscliparea = tssing.atranscliparea; // should scan along the line looking for a spot. if (!lam0valid && !lam1valid) TN.emitMessage("Both ends out, should scan"); // now we enter a loop to narrow down the range. for (int ip = 0; ip < sscratch.noplaceindexlimitpullback; ip++) { //TN.emitMessage("lam scan " + lam0 + (lam0valid ? "(*)" : "( )") + " " + lam1 + (lam1valid ? "(*)" : "( )")); // quit if accurate enough if (sscratch.pleng * (lam1 - lam0) <= ssb.pulltolerance) break; sscratch.placeindex++; double lammid = (lam0 + lam1) / 2; TSSymbSing tssinglammid = new TSSymbSing(oss); tssinglammid.Setpaxistrans(sscratch.BuildAxisTransT(lammid)); boolean lammidvalid = IsSymbolsPositionValid(tssinglammid); // decide which direction to favour // we should be scanning the intermediate places if neither end is in. if (lammidvalid) { lam1 = lammid; //lam1atranscliparea = tssing.atranscliparea; //lam1axistrans = tssing.paxistrans; tssinglam1 = tssinglammid; lam1valid = lammidvalid; } else { lam0 = lammid; //lam0atranscliparea = tssing.atranscliparea; //lam0axistrans = tssing.paxistrans; tssinglam0 = tssinglammid; lam0valid = lammidvalid; } if (lam0valid) break; } if (lam0valid) { //tssing.paxistrans = lam0axistrans; //tssing.atranscliparea = lam0atranscliparea; return tssinglam0; } if (lam1valid) { //tssing.paxistrans = lam1axistrans; //tssing.atranscliparea = lam1atranscliparea; return tssinglam1; } return null; } //////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////// // loop over the random variation. (it's a one time loop if it's a single symbol object) TSSymbSing MRelaySymbol(OneSSymbol oss, SSymbScratch sscratch) { // use of sscratch.placeindex is hack over multiple symbols for (int ip = 0; ip < sscratch.noplaceindexlimitrand; ip++) { if (!sscratch.BuildAxisTransSetup(oss, sscratch.placeindexabs)) // changed from placeindex! return null; sscratch.placeindexabs++; TSSymbSing tssing = MRelaySymbolT(oss, sscratch); if (tssing != null) { tssing.splaceindex = sscratch.placeindex; return tssing; } // quit if not a random moving type. if (!oss.ssb.bMoveable && (oss.ssb.iLattice == 0)) break; } return null; } ///////////////////////////////////////////// void MRelaySymbolsPositionBatch(List osslist) { // initialize the axes in the scratch areas if (osslist.size() > iactivesymbols.length) TN.emitWarning("Toomany active symbols"); int tniactivesymbols = Math.min(osslist.size(), iactivesymbols.length); for (int i = 0; i < tniactivesymbols; i++) { OneSSymbol oss = osslist.get(i); if (sscratcharr.size() <= i) sscratcharr.add(new SSymbScratch()); // extend the array SSymbScratch sscratch = sscratcharr.get(i); iactivesymbols[i] = i; assert oss.nsmposvalid == 0; // set outside assert ((oss.op.pthcca != null) && (oss.ssb.gsym != null) && (oss.ssb.symbolareafillcolour == null)); sscratch.InitAxis(oss, true, oss.op.pthcca.saarea); sscratch.placeindex = 0; // layout index variables. sscratch.placeindexabs = 0; sscratch.noplaceindexlimitpullback = 20; // layout index variables. sscratch.noplaceindexlimitrand = 20; lgpsympss[i] = null; oss.gpsymps = null; } // now reloop and relayout, selecting at random int niactivesymbols = tniactivesymbols; while (niactivesymbols != 0) { // select random symbol from list (this selection will in future be weighted) // not perfect when it combines two areas, one of which also has sand, but interesting enough int ixa = sscratcharr.get(0).ran.nextInt(niactivesymbols); int i = iactivesymbols[ixa]; OneSSymbol oss = osslist.get(i); SSymbScratch sscratch = sscratcharr.get(i); boolean blayoutmore = true; TSSymbSing tssing = MRelaySymbol(oss, sscratch); if (tssing != null) { AddInterfToBoxset(tssing); oss.nsmposvalid++; lgpsympss[i] = tssing.oss.AppendTransformedCopy(tssing.paxistrans, lgpsympss[i]); //oss.gpsymps = oss.AppendTransformedCopy(tssing.paxistrans, oss.gpsymps); } else blayoutmore = false; if ((oss.ssb.nmultiplicity != -1) && (oss.nsmposvalid >= oss.ssb.nmultiplicity)) blayoutmore = false; if ((oss.ssb.maxplaceindex != -1) && (sscratch.placeindex > oss.ssb.maxplaceindex)) blayoutmore = false; if (!blayoutmore) { // kill off this representative iactivesymbols[ixa] = iactivesymbols[--niactivesymbols]; if (sscratch.placeindex > 1) TN.emitMessage("S:" + oss.ssb.gsymname + " placeindex " + ((oss.ssb.maxplaceindex != -1) && (sscratch.placeindex > oss.ssb.maxplaceindex) ? "(maxed) ": "") + sscratch.placeindex + " of symbols " + oss.nsmposvalid); } //else // System.out.println("Lay down: " + oss.ssb.gsymname + " " + oss.nsmposvalid); } // now put the general paths representing the symbolic data into the symbols for (int i = 0; i < tniactivesymbols; i++) { OneSSymbol oss = osslist.get(i); oss.gpsymps = lgpsympss[i]; } } //////////////////////////////////////////////////////////////////////////////// void SLayoutMutualSymbols(List vmconnpaths, boolean lbmorethanoneconnectedcomponent) { // sort the symbols into two batches //assert latticesymbols.isEmpty() && othersymbols.isEmpty(); latticesymbols.clear(); // cleanup in case there had been an exception leaving a mess othersymbols.clear(); bmorethanoneconnectedcomponent = lbmorethanoneconnectedcomponent; for (OnePath op : vmconnpaths) { for (OneSSymbol oss : op.vpsymbols) { oss.nsmposvalid = 0; if ((oss.ssb.symbolareafillcolour == null) && (oss.ssb.gsym != null)) { if (oss.ssb.bBuildSymbolLatticeAcrossArea) latticesymbols.add(oss); else othersymbols.add(oss); } } } for (OneSSymbol oss : othersymbols) { othersymbol.clear(); othersymbol.add(oss); // one element array MRelaySymbolsPositionBatch(othersymbol); } othersymbol.clear(); othersymbols.clear(); if (!latticesymbols.isEmpty()) MRelaySymbolsPositionBatch(latticesymbols); latticesymbols.clear(); } } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // controls the layout in a set of overlapping component areas class MutualComponentArea { List ccamutual = new ArrayList(); SortedSet osamutual = new TreeSet(); List vmconnpaths = new ArrayList(); Rectangle2D mbounds = null; double sumsymdim = 0.0; int nsymdim = 0; boolean bsymbollaidout = false; //////////////////////////////////////////////////////////////////////////////// void MergeIn(ConnectiveComponentAreas scca) { ccamutual.add(scca); osamutual.addAll(scca.vconnareas); vmconnpaths.addAll(scca.vconnpaths); assert (scca.pvconncommutual == null); scca.pvconncommutual = this; if (scca.saarea != null) { if (mbounds == null) mbounds = scca.saarea.getBounds2D(); else mbounds.add(scca.saarea.getBounds2D()); } // collate some kind of average symbol width and height for (OnePath op : scca.vconnpaths) { for (OneSSymbol oss : op.vpsymbols) { sumsymdim += oss.ssb.avgsymdim; nsymdim += (oss.ssb.avgsymdim != 0.0 ? 1 : 0); } } } //////////////////////////////////////////////////////////////////////////////// boolean hit(GraphicsAbstraction ga, Rectangle windowrect) { for (OneSArea osa : osamutual) // could equally loop through ccamutual and look at saarea { if ((osa.aarea != null) && ga.hit(windowrect, osa.aarea, false)) return true; } return false; } //////////////////////////////////////////////////////////////////////////////// void LayoutMutualSymbols(MutualComponentAreaScratch mcascratch) // all symbols in this batch { mcascratch.BuildBoxset(mbounds, (nsymdim != 0 ? sumsymdim / nsymdim : 0.0)); mcascratch.SLayoutMutualSymbols(vmconnpaths, (ccamutual.size() > 1)); mcascratch.FreeBoxCells(); bsymbollaidout = true; } }; tunnelx-20140102.orig/src/SketchDisplay.java0000644000000000000000000017622512261213471015504 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JCheckBoxMenuItem; import javax.swing.JToggleButton; import javax.swing.JPanel; import javax.swing.JCheckBox; import javax.swing.JButton; import javax.swing.JTextField; import javax.swing.JLabel; import javax.swing.JTabbedPane; import javax.swing.JSplitPane; import javax.swing.JTextArea; import java.awt.Graphics; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.GridLayout; import javax.swing.BoxLayout; import java.awt.FileDialog; import java.awt.Image; import java.awt.Insets; import java.awt.Dimension; import java.io.IOException; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.WindowEvent; import java.awt.event.WindowAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseAdapter; import java.awt.event.KeyEvent; import java.awt.event.KeyAdapter; import javax.swing.Action; import javax.swing.AbstractAction; import javax.swing.KeyStroke; import javax.swing.JSlider; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.geom.AffineTransform; import java.util.List; import java.util.ArrayList; import java.util.Set; import javax.swing.JProgressBar; // // // SketchDisplay // // // this class contains the whole outer set of options and buttons class SketchDisplay extends JFrame { MainBox mainbox; // the panel which holds the sketch graphics SketchGraphics sketchgraphicspanel; // the window with the symbols SymbolsDisplay symbolsdisplay; // the menu bar JMenuBar menubar = new JMenuBar(); // file menu JMenu menufile = new JMenu("File"); JMenuItem miCopyCentrelineElev = new JMenuItem("Copy Centreline Elev"); JMenuItem miSaveSketch = new JMenuItem("Save"); JMenuItem miSaveSketchAs = new JMenuItem("Save As..."); JMenuItem miUploadSketch = new JMenuItem("Upload"); JMenuItem miMakeImages = new JMenuItem("Make images"); JMenuItem doneitem = new JMenuItem("Close"); SketchLineStyle sketchlinestyle; SketchSubsetPanel subsetpanel; SelectedSubsetStructure selectedsubsetstruct; SketchBackgroundPanel backgroundpanel; SketchInfoPanel infopanel; SketchPrintPanel printingpanel; SketchSecondRender secondrender; SketchZTiltPanel ztiltpanel; TodeNodePanel todenodepanel; JTabbedPane bottabbedpane; ///////////////////////////////////////////// // inactivate case class SketchHide extends WindowAdapter implements ActionListener { void CloseWindow() { //mainbox.symbolsdisplay.hide(); sketchgraphicspanel.ClearSelection(true); setVisible(false); } public void windowClosing(WindowEvent e) { CloseWindow(); } public void actionPerformed(ActionEvent e) { CloseWindow(); } } ///////////////////////////////////////////// // View menu actions ///////////////////////////////////////////// public class AcViewac extends AbstractAction { int viewaction; KeyStroke ks; public AcViewac(String name, String shdesc, KeyStroke lks, int lviewaction) { super(name); ks = lks; putValue(SHORT_DESCRIPTION, shdesc); viewaction = lviewaction; } public void actionPerformed(ActionEvent e) { if (viewaction == 4) sketchgraphicspanel.Scale(0.5F); else if (viewaction == 5) sketchgraphicspanel.Scale(2.0F); else if (viewaction == 6) sketchgraphicspanel.Translate(0.2F, 0.0F); else if (viewaction == 7) sketchgraphicspanel.Translate(-0.2F, 0.0F); else if (viewaction == 8) sketchgraphicspanel.Translate(0.0F, 0.2F); else if (viewaction == 9) sketchgraphicspanel.Translate(0.0F, -0.2F); else if (viewaction == 10) sketchgraphicspanel.Translate(0.0F, 0.0F); else if (viewaction == 124) sketchgraphicspanel.Rotate(5.0F); else if (viewaction == 125) sketchgraphicspanel.Rotate(-5.0F); else if (viewaction == 126) ztiltpanel.MoveTiltPlane(1); else if (viewaction == 127) ztiltpanel.MoveTiltPlane(-1); else if (viewaction == 128) sketchgraphicspanel.ElevBackImageWarp(); else if (viewaction == 122) sketchgraphicspanel.TiltView(15.0); else if (viewaction == 123) sketchgraphicspanel.TiltView(-15.0); else if (viewaction == 21) backgroundpanel.SetGridOrigin(true); else if (viewaction == 22) backgroundpanel.SetGridOrigin(false); // 1, 2, 3, 11, 12, 121 else sketchgraphicspanel.MaxAction(viewaction); } } // would like to use VK_RIGHT instead of VK_F12, but is not detected. int CTRL_DOWN_MASK = java.awt.event.InputEvent.CTRL_MASK; AcViewac acvMax = new AcViewac("Max", "Maximize View", null, 2); AcViewac acvCentre = new AcViewac("Centre", "Centre View", null, 1); AcViewac acvMaxSubset = new AcViewac("Max Subset", "Maximize Subset View", KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD5, 0), 12); AcViewac acvMaxSelect = new AcViewac("Max Select", "Maximize Select View", null, 121); AcViewac acvCentreSubset = new AcViewac("Centre Subset", "Centre Subset View", null, 11); AcViewac acvUpright = new AcViewac("Upright", "Upright View", null, 3); AcViewac acvScaledown = new AcViewac("Scale Down", "Zoom out", KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD3, 0), 4); AcViewac acvScaleup = new AcViewac("Scale Up", "Zoom in", KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD9, 0), 5); AcViewac acvRight = new AcViewac("Right", "Translate view right", KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD6, 0), 6); AcViewac acvLeft = new AcViewac("Left", "Translate view left", KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD4, 0), 7); AcViewac acvUp = new AcViewac("Up", "Translate view up", KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD2, 0), 8); AcViewac acvDown = new AcViewac("Down", "Translate view down", KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD8, 0), 9); AcViewac acvSetGridOrig = new AcViewac("Set Grid Orig", "Move the grid origin to the start node of selected line", null, 21); AcViewac acvResetGridOrig =new AcViewac("Reset Grid Orig", "Move the grid origin to original place", null, 22); AcViewac acvRedraw = new AcViewac("Redraw", "Redraw screen", null, 10); AcViewac acvTiltOver = new AcViewac("Tilt Over", "Tilt viewing plane away from face", null, 122); AcViewac acvTiltBack = new AcViewac("Tilt Back", "Tilt viewing plane back towards face", null, 123); AcViewac acvRotateRight = new AcViewac("Rotate right", "Rotate viewing plane clockwise", KeyStroke.getKeyStroke(KeyEvent.VK_R, java.awt.event.InputEvent.ALT_DOWN_MASK), 124); AcViewac acvRotateLeft = new AcViewac("Rotate left", "Rotate viewing plane anti-clockwise", KeyStroke.getKeyStroke(KeyEvent.VK_L, java.awt.event.InputEvent.ALT_DOWN_MASK), 125); AcViewac acvMovePlaneDown =new AcViewac("Move plane down", "tilt plane", KeyStroke.getKeyStroke(KeyEvent.VK_O, java.awt.event.InputEvent.ALT_DOWN_MASK), 126); AcViewac acvMovePlaneUp = new AcViewac("Move plane up", "tilt plane", KeyStroke.getKeyStroke(KeyEvent.VK_U, java.awt.event.InputEvent.ALT_DOWN_MASK), 127); AcViewac acvElevImageWarp =new AcViewac("Elev Image Warp", "Selected line shears background image", null, 128); // view menu JMenu menuView = new JMenu("View"); AcViewac[] acViewarr = { acvMaxSubset, acvMaxSelect, acvMax, acvCentre, acvCentreSubset, acvUpright, acvScaledown, acvScaleup, acvRight, acvLeft, acvUp, acvDown, acvRotateLeft, acvRotateRight, acvMovePlaneDown, acvMovePlaneUp, acvSetGridOrig, acvResetGridOrig, acvRedraw, acvTiltOver, acvTiltBack, acvElevImageWarp }; ///////////////////////////////////////////// // Display menu actions ///////////////////////////////////////////// public class AcDispchbox extends AbstractAction { int backrepaint; public AcDispchbox(String name, String shdesc, int lbackrepaint) { super(name); putValue(SHORT_DESCRIPTION, shdesc); backrepaint = lbackrepaint; } public void actionPerformed(ActionEvent e) { if (backrepaint == 0) sketchgraphicspanel.RedrawBackgroundView(); else { if (backrepaint == 2) selectedsubsetstruct.UpdateTreeSubsetSelection(subsetpanel.pansksubsetstree); sketchgraphicspanel.RedoBackgroundView(); } } } AcDispchbox acdCentreline = new AcDispchbox("Centreline", "Centreline visible", 0); AcDispchbox acdStationNames = new AcDispchbox("Station Names", "Station names visible", 0); AcDispchbox acdStationAlts = new AcDispchbox("Station Altitudes", "Station altitudes visible", 0); AcDispchbox acdXSections = new AcDispchbox("XSections", "Cross sections visible", 0); AcDispchbox acdTubes = new AcDispchbox("Tubes", "Tubes visible", 0); AcDispchbox acdAxes = new AcDispchbox("Axes", "Axes visible", 0); AcDispchbox acdDepthCols = new AcDispchbox("Depth Colours", "Depth colours visible", 0); AcDispchbox acdShowNodes = new AcDispchbox("Show Nodes", "Path nodes visible", 0); AcDispchbox acdShowBackground = new AcDispchbox("Show Background", "Background image visible", 1); AcDispchbox acdShowGrid = new AcDispchbox("Show Grid", "Background grid visible", 1); AcDispchbox acdTransitiveSubset = new AcDispchbox("Transitive Subset", "View selected subsets and branches", 2); AcDispchbox acdInverseSubset = new AcDispchbox("Inverse Subset", "Grey out the selected subsets", 2); AcDispchbox acdHideSplines = new AcDispchbox("Hide Splines", "Show all paths as non-splined", 1); AcDispchbox acdNotDotted = new AcDispchbox("Not dotted", "Make lines not dotted", 1); AcDispchbox acdShowTilt = new AcDispchbox("Show tilted in z", "The tilt backwards feature", 0); JCheckBoxMenuItem miCentreline = new JCheckBoxMenuItem(acdCentreline); JCheckBoxMenuItem miStationNames = new JCheckBoxMenuItem(acdStationNames); JCheckBoxMenuItem miStationAlts = new JCheckBoxMenuItem(acdStationAlts); JCheckBoxMenuItem miDepthCols = new JCheckBoxMenuItem(acdDepthCols); JCheckBoxMenuItem miShowNodes = new JCheckBoxMenuItem(acdShowNodes); JCheckBoxMenuItem miShowBackground = new JCheckBoxMenuItem(acdShowBackground); JCheckBoxMenuItem miShowGrid = new JCheckBoxMenuItem(acdShowGrid); JCheckBoxMenuItem miTransitiveSubset = new JCheckBoxMenuItem(acdTransitiveSubset); JCheckBoxMenuItem miInverseSubset = new JCheckBoxMenuItem(acdInverseSubset); JCheckBoxMenuItem miHideSplines = new JCheckBoxMenuItem(acdHideSplines); JCheckBoxMenuItem miNotDotted = new JCheckBoxMenuItem(acdNotDotted); JCheckBoxMenuItem miThinZheightsel = new JCheckBoxMenuItem("Thin Z Selection", false); AcActionac acvThinZheightselWiden = new AcActionac("Widen Z Selection", "Widen Z Selection", null, 96); AcActionac acvThinZheightselNarrow = new AcActionac("Narrow Z Selection", "Narrow Z Selection", null, 97); JCheckBoxMenuItem miShowTilt = new JCheckBoxMenuItem(acdShowTilt); // display menu. JMenu menuDisplay = new JMenu("Display"); JCheckBoxMenuItem[] miDisplayarr = { miCentreline, miStationNames, miStationAlts, miShowNodes, miDepthCols, miShowBackground, miShowGrid, miTransitiveSubset, miInverseSubset, miHideSplines, miNotDotted, miShowTilt }; ///////////////////////////////////////////// // Motion menu JCheckBoxMenuItem miTabletMouse = new JCheckBoxMenuItem("Tablet Mouse", false); JCheckBoxMenuItem miEnableRotate = new JCheckBoxMenuItem("Enable rotate", false); JCheckBoxMenuItem miTrackLines = new JCheckBoxMenuItem("Track Lines", false); JCheckBoxMenuItem miShearWarp = new JCheckBoxMenuItem("Shear Warp", false); JCheckBoxMenuItem miDefaultSplines = new JCheckBoxMenuItem("Splines Default", true); JCheckBoxMenuItem miSnapToGrid = new JCheckBoxMenuItem("Snap to Grid", false); JCheckBoxMenuItem miEnableDoubleClick =new JCheckBoxMenuItem("Enable double-click",true); JMenu menuMotion = new JMenu("Motion"); JCheckBoxMenuItem[] miMotionarr = { miTabletMouse, miEnableRotate, miTrackLines, miShearWarp, miDefaultSplines, miSnapToGrid, miEnableDoubleClick }; ///////////////////////////////////////////// // Action menu actions ///////////////////////////////////////////// public class AcActionac extends AbstractAction { int acaction; KeyStroke ks; public AcActionac(String name, String shdesc, KeyStroke lks, int lacaction) { super(name); ks = lks; putValue(SHORT_DESCRIPTION, shdesc); acaction = lacaction; } ///////////////////////////////////////////// public void actionPerformed(ActionEvent e) { if (acaction == 4) { sketchgraphicspanel.ClearSelection(false); sketchgraphicspanel.repaint(); } else if (acaction == 5) sketchgraphicspanel.DeleteSel(); else if (acaction == 6) sketchgraphicspanel.FuseCurrent(miShearWarp.isSelected()); else if (acaction == 7) sketchgraphicspanel.BackSelUndo(); else if (acaction == 8) sketchgraphicspanel.ReflectCurrent(); else if (acaction == 9) sketchgraphicspanel.SetAsAxis(); else if (acaction == 83) sketchgraphicspanel.Makesquare(); else if (acaction == 10) sketchgraphicspanel.MakePitchUndercut(); else if ((acaction == 11) || (acaction == 12)) { SketchLineStyle.SetStrokeWidths(SketchLineStyle.strokew * (acaction == 11 ? 2.0F : 0.5F), miNotDotted.isSelected()); if (todenodepanel != null) todenodepanel.BuildSpirals(); sketchgraphicspanel.RedrawBackgroundView(); } else if (acaction == 18) sketchgraphicspanel.SelectConnectedSetsFromSelection(); else if (acaction == 14) sketchgraphicspanel.MoveGround(false); else if (acaction == 15) sketchgraphicspanel.MoveGround(true); else if (acaction == 16) backgroundpanel.NewBackgroundFile(); else if (acaction == 177) backgroundpanel.UploadBackgroundFile(); else if (acaction == 17) sketchlinestyle.pthstyleareasigtab.StyleMappingCopyButt(true); else if (acaction == 20) { SketchLineStyle.bDepthColours = false; SketchLineStyle.bPathSubsetColours = false; sketchgraphicspanel.RedrawBackgroundView(); } else if (acaction == 21) { SketchLineStyle.SetIColsByZ(sketchgraphicspanel.tsketch.vpaths, sketchgraphicspanel.tsvpathsviz, sketchgraphicspanel.tsketch.vnodes, sketchgraphicspanel.tsketch.vsareas); sketchgraphicspanel.RedrawBackgroundView(); } else if (acaction == 24) { SketchLineStyle.bDepthColours = false; SketchLineStyle.bPathSubsetColours = true; sketchgraphicspanel.RedrawBackgroundView(); } else if (acaction == 22) { OnePathNode ops = (sketchgraphicspanel.currpathnode != null ? sketchgraphicspanel.currpathnode : (sketchgraphicspanel.currgenpath != null ? sketchgraphicspanel.currgenpath.pnstart : null)); SketchLineStyle.SetIColsProximity(0, sketchgraphicspanel.tsketch, ops); sketchgraphicspanel.RedrawBackgroundView(); } else if (acaction == 23) { OnePathNode ops = (sketchgraphicspanel.currpathnode != null ? sketchgraphicspanel.currpathnode : (sketchgraphicspanel.currgenpath != null ? sketchgraphicspanel.currgenpath.pnstart : null)); sketchlinestyle.SetIColsProximity(1, sketchgraphicspanel.tsketch, ops); sketchgraphicspanel.RedrawBackgroundView(); } // the automatic actions which should be running constantly in a separate thread else if ((acaction == 51) || (acaction == 58)) { sketchgraphicspanel.UpdateZNodes(); // do everything if (acaction == 58) { sketchgraphicspanel.UpdateSAreas(); sketchgraphicspanel.GUpdateSymbolLayout(true, visiprogressbar); sketchgraphicspanel.bNextRenderDetailed = true; } } else if (acaction == 52) sketchgraphicspanel.UpdateSAreas(); else if ((acaction == 53) || (acaction == 54)) sketchgraphicspanel.GUpdateSymbolLayout((acaction == 54), visiprogressbar); else if (acaction == 56) // detail render sketchgraphicspanel.bNextRenderDetailed = true; else if (acaction == 57) // printing proximities to the command line { ProximityDerivation pd = new ProximityDerivation(sketchgraphicspanel.tsketch); pd.PrintCNodeProximity(3); // uses default settings in the pd.parainstancequeue } else if (acaction == 59) ReloadFontcolours(); // subsets else if (acaction == 72) subsetpanel.AddSelCentreToCurrentSubset(); else if (acaction == 77) subsetpanel.AddRemainingCentreToCurrentSubset(); else if (acaction == 73) subsetpanel.PartitionRemainsByClosestSubset(); else if (acaction == 733) subsetpanel.PartitionRemainsByClosestSubsetDatetype(); else if (acaction == 74) subsetpanel.PutSelToSubset(true); else if (acaction == 75) subsetpanel.PutSelToSubset(false); else if (acaction == 76) subsetpanel.pansksubsetstree.clearSelection(); else if (acaction == 78) subsetpanel.DeleteTodeleteSubset(); else if (acaction == 79) subsetpanel.RemoveAllFromSubset(); else if (acaction == 71) subsetpanel.ElevationSubset(true); else if (acaction == 711) subsetpanel.ElevationSubset(false); else if (acaction == 70) subsetpanel.sascurrent.ToggleViewHidden(selectedsubsetstruct.vsselectedsubsets, miTransitiveSubset.isSelected()); // these ones don't actually need the repaint else if (acaction == 80) sketchlinestyle.SetConnTabPane("Symbol"); else if (acaction == 81) sketchlinestyle.SetConnTabPane("Label"); else if (acaction == 82) sketchlinestyle.SetConnTabPane("Area-Sig"); else if (acaction == 91) sketchgraphicspanel.bNextRenderPinkDownSketch = true; else if (acaction == 93) { sketchgraphicspanel.bNextRenderAreaStripes = true; for (OneSArea osa : sketchgraphicspanel.tsketch.vsareas) osa.Dgptriangulation = new DelTriangulation(osa); } else if (acaction == 95) sketchgraphicspanel.ImportSketch(mainbox.tunnelfilelist.GetSelectedSketchLoad(), miImportCentreSubsetsU.isSelected(), miClearCentreSubsets.isSelected(), miImportNoCentrelines.isSelected()); else if (acaction == 96) ztiltpanel.WidenTiltPlane(1); else if (acaction == 97) ztiltpanel.WidenTiltPlane(-1); // paper sizes else if (acaction == 405) sketchgraphicspanel.ImportPaperM("A5", 0.1485F, 0.210F); else if (acaction == 415) sketchgraphicspanel.ImportPaperM("A5_land", 0.210F, 0.1485F); else if (acaction == 404) sketchgraphicspanel.ImportPaperM("A4", 0.210F, 0.297F); else if (acaction == 414) sketchgraphicspanel.ImportPaperM("A4_land", 0.297F, 0.210F); else if (acaction == 403) sketchgraphicspanel.ImportPaperM("A3", 0.297F, 0.420F); else if (acaction == 413) sketchgraphicspanel.ImportPaperM("A3_land", 0.420F, 0.297F); else if (acaction == 402) sketchgraphicspanel.ImportPaperM("A2", 0.420F, 0.594F); else if (acaction == 412) sketchgraphicspanel.ImportPaperM("A2_land", 0.594F, 0.420F); else if (acaction == 401) sketchgraphicspanel.ImportPaperM("A1", 0.594F, 0.840F); else if (acaction == 411) sketchgraphicspanel.ImportPaperM("A1_land", 0.840F, 0.594F); else if (acaction == 400) sketchgraphicspanel.ImportPaperM("A0", 0.840F, 1.188F); else if (acaction == 410) sketchgraphicspanel.ImportPaperM("A0_land", 1.188F, 0.840F); // new survex label controls interface else if (acaction == 501) ImportSketchCentrelineFile(null); else if (acaction == 502) ImportAtlasTemplate(); else if (acaction == 510) ImportCentrelineLabel("preview"); else if ((acaction == 511) || (acaction == 512)) { ImportCentrelineLabel(acaction == 511 ? "normal" : "TOPelevation"); sketchgraphicspanel.MaxAction(2); } sketchgraphicspanel.repaint(); } } // action menu // would like to use VK_RIGHT instead of VK_F12, but is not detected. AcActionac acaDeselect = new AcActionac("Deselect", "Deselect", null, 4); AcActionac acaDelete = new AcActionac("Delete", "Delete selection", KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, CTRL_DOWN_MASK), 5); AcActionac acaFuse = new AcActionac("Fuse", "Fuse paths", null, 6); AcActionac acaBackNode = new AcActionac("Back", "Remove last hit", KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, CTRL_DOWN_MASK), 7); AcActionac acaReflect = new AcActionac("Reflect", "Reflect path", null, 8); AcActionac acaSetasaxis = new AcActionac("Set As Axis", "Set As Axis", null, 9); AcActionac acaMakesquare = new AcActionac("Make square", "Make square", null, 83); AcActionac acaPitchUndercut = new AcActionac("Pitch Undercut", "Drop-down an invisible copy of a pitch boundary", null, 10); AcActionac acaStrokeThin = new AcActionac("Stroke >>", "Thicker lines", KeyStroke.getKeyStroke(KeyEvent.VK_GREATER, CTRL_DOWN_MASK), 11); AcActionac acaStrokeThick = new AcActionac("Stroke <<", "Thinner lines", KeyStroke.getKeyStroke(KeyEvent.VK_LESS, CTRL_DOWN_MASK), 12); AcActionac acaMovePicture = new AcActionac("Shift View", "Moves view by according to path", null, 14); AcActionac acaMoveBackground = new AcActionac("Shift Ground", "Moves background image by according to path", null, 15); AcActionac acaAddImage = new AcActionac("Add Image", "Adds a new background image to the sketch", null, 16); AcActionac acaReloadImage = new AcActionac("Select Image", "Copies this background image to background of the sketch", null, 17); // could grey this one too AcActionac acaUploadImage = new AcActionac("Upload Back Image", "Uploads this background image to the server", null, 177); AcActionac acaSelectComponent =new AcActionac("Component", "Selects Connected Component for selected edge", null, 18); JCheckBoxMenuItem miDeleteCentrelines = new JCheckBoxMenuItem("Allow Delete Centrelines", false); // connective type specifiers AcActionac acaConntypesymbols =new AcActionac("Add symbols", "Put symbols on connective path", null, 80); AcActionac acaConntypelabel = new AcActionac("Write Text", "Put label on connective path", null, 81); AcActionac acaConntypearea = new AcActionac("Area signal", "Put area signal on connective path", null, 82); JMenu menuAction = new JMenu("Action"); AcActionac[] acActionarr = { acaDeselect, acaDelete, acaFuse, acaBackNode, acaReflect, acaPitchUndercut, acaStrokeThin, acaStrokeThick, acaSetasaxis, acaMakesquare, acaMovePicture, acaMoveBackground, acaAddImage, acaUploadImage, acaSelectComponent, acaConntypesymbols, acaConntypelabel, acaConntypearea }; AcActionac[] acPathcomarr = { acaReflect, acaFuse, acaSelectComponent, acaBackNode, acaDelete }; // auto menu AcActionac acaSetZonnodes = new AcActionac("Update Node Z", "Set node heights from centreline", null, 51); AcActionac acaUpdateSAreas = new AcActionac("Update Areas", "Update automatic areas", null, 52); AcActionac acaUpdateSymbolLayout = new AcActionac("Update Symbol Lay", "Update symbol layout in view", null, 53); AcActionac acaUpdateSymbolLayoutAll = new AcActionac("Update Symbol Lay All", "Update symbol layout Everywhere", null, 54); AcActionac acaDetailRender = new AcActionac("Detail Render", "Detail Render", null, 56); AcActionac acaUpdateEverything = new AcActionac("Update Everything", "All updates in a row", null, 58); AcActionac acaReloadFontcolours = new AcActionac("Reload Fontcolours", "Makes all the subsets again", null, 59); JMenu menuAuto = new JMenu("Update"); AcActionac[] acAutoarr = { acaSetZonnodes, acaUpdateSAreas, acaUpdateSymbolLayout, acaUpdateSymbolLayoutAll, acaDetailRender, acaUpdateEverything, acaReloadFontcolours }; // import menu AcActionac acaPrevDownsketch = new AcActionac("Preview Down Sketch", "See the sketch that will be distorted", null, 91); AcActionac acaImportDownSketch = new AcActionac("Import Down Sketch", "Bring in the distorted sketch", null, 95); JCheckBoxMenuItem miImportTitleSubsets = new JCheckBoxMenuItem("*title Subsets", true); JCheckBoxMenuItem miImportDateSubsets = new JCheckBoxMenuItem("*date Subsets", false); JCheckBoxMenuItem miImportCentreSubsetsU = new JCheckBoxMenuItem("Import Cen-Subsets", true); JCheckBoxMenuItem miClearCentreSubsets = new JCheckBoxMenuItem("Clear Cen-Subsets", true); JCheckBoxMenuItem miImportNoCentrelines = new JCheckBoxMenuItem("Exclude Centrelines", true); JCheckBoxMenuItem miUseSurvex = new JCheckBoxMenuItem("Use Survex", false); AcActionac acaStripeAreas = new AcActionac("Stripe Areas", "See the areas filled with stripes", null, 93); AcActionac acaImportA5 = new AcActionac("Make A5", "Make A5 rectangle", null, 405); AcActionac acaImportA5landscape = new AcActionac("Make A5 landscape", "Make A5 rectangle landscape", null, 415); AcActionac acaImportA4 = new AcActionac("Make A4", "Make A4 rectangle", null, 404); AcActionac acaImportA4landscape = new AcActionac("Make A4 landscape", "Make A4 rectangle landscape", null, 414); AcActionac acaImportA3 = new AcActionac("Make A3", "Make A3 rectangle", null, 403); AcActionac acaImportA3landscape = new AcActionac("Make A3 landscape", "Make A3 rectangle landscape", null, 413); AcActionac acaImportA2 = new AcActionac("Make A2", "Make A2 rectangle", null, 402); AcActionac acaImportA2landscape = new AcActionac("Make A2 landscape", "Make A2 rectangle landscape", null, 412); AcActionac acaImportA1 = new AcActionac("Make A1", "Make A1 rectangle", null, 401); AcActionac acaImportA1landscape = new AcActionac("Make A1 landscape", "Make A1 rectangle landscape", null, 411); AcActionac acaImportA0 = new AcActionac("Make A0", "Make A0 rectangle", null, 400); AcActionac acaImportA0landscape = new AcActionac("Make A0 landscape", "Make A0 rectangle", null, 410); AcActionac[] acmenuPaper = { acaImportA5, acaImportA5landscape, acaImportA4, acaImportA4landscape, acaImportA3, acaImportA3landscape, acaImportA2, acaImportA2landscape, acaImportA1, acaImportA1landscape, acaImportA0, acaImportA0landscape }; AcActionac acaImportCentrelineFile = new AcActionac("Import Survex File", "Loads a survex file into a Label", null, 501); AcActionac acaPreviewLabelWireframe = new AcActionac("Wireframe view", "Previews selected SVX data as Wireframe in Aven if available", null, 510); AcActionac acaImportLabelCentreline = new AcActionac("Import Centreline", "Imports selected SVX data from label", null, 511); AcActionac acaImportLabelCentrelineElev = new AcActionac("Import Centreline Elev", "Imports selected SVX data from label DistoX elevfile", null, 512); AcActionac acaImportAtlasTemplate =new AcActionac("Import Atlas", "Makes atlas from template", null, 502); JMenu menuImport = new JMenu("Import"); JMenu menuImportPaper = new JMenu("Import Paper"); // colour menu AcActionac acaColourDefault = new AcActionac("Default", "Plain colours", null, 20); AcActionac acaColourByZ = new AcActionac("Height", "Depth colours", null, 21); AcActionac acaColourByProx = new AcActionac("Proximity", "Visualize proximity to selection", null, 22); AcActionac acaColourByCnodeWeight =new AcActionac("CNode Weights", "Visualize centreline node weights", null, 23); AcActionac acaColourBySubset = new AcActionac("By Subset", "Set edge colours according to subset area colour", null, 24); AcActionac acaPrintProximities = new AcActionac("Print Prox", "Print proximities of nodes to centrelines", null, 57); JMenu menuColour = new JMenu("Colour"); // subset menu JMenu menuSubset = new JMenu("Subset"); AcActionac acaAddCentreSubset = new AcActionac("Add Centrelines", "Add all centrelines from selected survey to subset", null, 72); AcActionac acaAddRestCentreSubset = new AcActionac("Add Rest Centrelines", "Add all centrelines not already in a subset", null, 77); AcActionac acaPartitionSubset = new AcActionac("Partition Remains", "Put paths into nearest subset", null, 73); AcActionac acaPartitionSubsetDates = new AcActionac("Partition Date Subsets", "Put paths into nearest date subset", null, 733); AcActionac acaAddToSubset = new AcActionac("Add to Subset", "Add selected paths to subset", null, 74); AcActionac acaRemoveFromSubset = new AcActionac("Remove from Subset", "Remove selected paths to subset", null, 75); AcActionac acaDeleteTodeleteSubset = new AcActionac("Delete 'todelete' Subset", "Delete all paths in the 'todelete' subset", null, 78); AcActionac acaClearSubsetContents = new AcActionac("Clear subset contents", "Remove all paths from subset", null, 79); AcActionac acaCleartreeSelection = new AcActionac("Clear subset selection", "Clear selections on subset tree", null, 76); AcActionac acaToggleViewHidden = new AcActionac("Toggle Hidden", "Change hidden subset settings", null, 70); AcActionac[] acSubsetarr = { acaToggleViewHidden, acaAddCentreSubset, acaAddRestCentreSubset, acaPartitionSubset, acaPartitionSubsetDates, acaAddToSubset, acaRemoveFromSubset, acaClearSubsetContents, acaDeleteTodeleteSubset, acaCleartreeSelection }; JCheckBoxMenuItem miAutoAddToSubset = new JCheckBoxMenuItem("Add new paths subset", false); JMenu menuElevation = new JMenu("Elevation"); AcActionac acaXCSubset = new AcActionac("XC subset", "Make new cross-section subset", null, 71); AcActionac acaElevationSubset = new AcActionac("Elevation subset", "Make new elevation subset", null, 711); AcActionac[] acElevarr = { acaXCSubset, acaElevationSubset, }; JProgressBar visiprogressbar = new JProgressBar(0, 100); //AcActionac acaAddCentreSubset = new AcActionac("Add Centrelines", "Add all centrelines from selected survey to subset", 0, 72); ///////////////////////////////////////////// ///////////////////////////////////////////// // set up the arrays SketchDisplay(MainBox lmainbox) { super("Sketch Display"); // symbols communication. mainbox = lmainbox; // it's important that the two panels are constructed in order. sketchgraphicspanel = new SketchGraphics(this); // the window with the symbols symbolsdisplay = new SymbolsDisplay(this); // sketch line style selection sketchlinestyle = new SketchLineStyle(symbolsdisplay, this); miSaveSketch.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { SaveSketch(0); } } ); menufile.add(miSaveSketch); miSaveSketchAs.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { SaveSketch(1); } } ); menufile.add(miSaveSketchAs); miUploadSketch.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { SaveSketch(2); } } ); menufile.add(miMakeImages); miMakeImages.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { MakeImages(); } } ); menufile.add(miUploadSketch); doneitem.addActionListener(new SketchHide()); menufile.add(doneitem); menubar.add(menufile); // view menu stuff. for (int i = 0; i < acViewarr.length; i++) { JMenuItem mi = new JMenuItem(acViewarr[i]); if (acViewarr[i].ks != null) mi.setAccelerator(acViewarr[i].ks); menuView.add(mi); } menubar.add(menuView); // setup the display menu responses for (int i = 0; i < miDisplayarr.length; i++) { boolean binitialstate = !(/*(miDisplayarr[i] == miShowBackground) ||*/ (miDisplayarr[i] == miStationNames) || (miDisplayarr[i] == miStationAlts) || (miDisplayarr[i] == miTransitiveSubset) || (miDisplayarr[i] == miInverseSubset) || (miDisplayarr[i] == miShowTilt) || ((miDisplayarr[i] == miHideSplines) && !OnePath.bHideSplines) || ((miDisplayarr[i] == miNotDotted) && !FileAbstraction.bIsUnixSystem)); miDisplayarr[i].setState(binitialstate); menuDisplay.add(miDisplayarr[i]); } menuDisplay.add(new JMenuItem(acaStripeAreas)); menuDisplay.add(miThinZheightsel); menuDisplay.add(new JMenuItem(acvThinZheightselWiden)); menuDisplay.add(new JMenuItem(acvThinZheightselNarrow)); menubar.add(menuDisplay); // yoke these checkboxes to ones in the background menu miShowBackground.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { if (backgroundpanel.cbshowbackground.isSelected() != miShowBackground.isSelected()) backgroundpanel.cbshowbackground.setSelected(miShowBackground.isSelected()); } } ); miShowGrid.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { if (backgroundpanel.cbshowgrid.isSelected() != miShowGrid.isSelected()) backgroundpanel.cbshowgrid.setSelected(miShowGrid.isSelected()); } } ); miHideSplines.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { ApplySplineChange(miHideSplines.isSelected()); } } ); miNotDotted.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { SketchLineStyle.SetStrokeWidths(SketchLineStyle.strokew, miNotDotted.isSelected()); } } ); miSnapToGrid.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { if (backgroundpanel.cbsnaptogrid.isSelected() != miSnapToGrid.isSelected()) backgroundpanel.cbsnaptogrid.setSelected(miSnapToGrid.isSelected()); } } ); miShowTilt.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { if (ztiltpanel.cbaShowTilt.isSelected() != miShowTilt.isSelected()) ztiltpanel.cbaShowTilt.setSelected(miShowTilt.isSelected()); } } ); miThinZheightsel.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { if (ztiltpanel.cbaThinZheightsel.isSelected() != miThinZheightsel.isSelected()) ztiltpanel.cbaThinZheightsel.setSelected(miThinZheightsel.isSelected()); ztiltpanel.ApplyZheightSelected(miThinZheightsel.isSelected()); } } ); // motion menu for (int i = 0; i < miMotionarr.length; i++) menuMotion.add(miMotionarr[i]); menubar.add(menuMotion); // action menu stuff. for (int i = 0; i < acActionarr.length; i++) { JMenuItem mi = new JMenuItem(acActionarr[i]); if (acActionarr[i].ks != null) mi.setAccelerator(acActionarr[i].ks); menuAction.add(mi); } menuAction.add(miDeleteCentrelines); menubar.add(menuAction); // auto menu for (int i = 0; i < acAutoarr.length; i++) menuAuto.add(new JMenuItem(acAutoarr[i])); menubar.add(menuAuto); // import menu menuImport.add(acaImportCentrelineFile); miUseSurvex.setSelected(FileAbstraction.SurvexExists()); miImportNoCentrelines.setToolTipText("Applies to Import Down Sketch only"); miDeleteCentrelines.setToolTipText("Enable deletion of centrelines as well as other types"); menuImport.add(miUseSurvex); menuImport.add(acaPreviewLabelWireframe); menuImport.add(miImportTitleSubsets); menuImport.add(miImportDateSubsets); menuImport.add(acaImportLabelCentreline); menuImport.add(acaImportLabelCentrelineElev); menuImport.add(new JMenuItem(acaPrevDownsketch)); menuImport.add(miImportNoCentrelines); menuImport.add(miImportCentreSubsetsU); menuImport.add(miClearCentreSubsets); menuImport.add(new JMenuItem(acaImportDownSketch)); for (int i = 0; i < acmenuPaper.length; i++) menuImportPaper.add(new JMenuItem(acmenuPaper[i])); menuImport.add(menuImportPaper); menuImportPaper.setToolTipText("Used to define the paper outline in a poster view"); menuImport.add(new JMenuItem(acaImportAtlasTemplate)); menubar.add(menuImport); // colour menu stuff. menuColour.add(new JMenuItem(acaColourDefault)); menuColour.add(new JMenuItem(acaColourByZ)); menuColour.add(new JMenuItem(acaColourByProx)); menuColour.add(new JMenuItem(acaColourByCnodeWeight)); menuColour.add(new JMenuItem(acaColourBySubset)); menuColour.add(new JMenuItem(acaPrintProximities)); menubar.add(menuColour); for (int i = 0; i < acElevarr.length; i++) menuElevation.add(new JMenuItem(acElevarr[i])); menubar.add(menuElevation); // subset menu stuff. menuSubset.add(new JMenuItem(acSubsetarr[0])); menuSubset.add(new JMenuItem(acSubsetarr[1])); menuSubset.add(miAutoAddToSubset); for (int i = 0; i < acSubsetarr.length; i++) menuSubset.add(new JMenuItem(acSubsetarr[i])); menubar.add(menuSubset); if (mainbox.instanthelp != null) { JMenu menuHelp = new JMenu("Help"); for (JMenuItem mihelp : mainbox.instanthelp.mihelps) menuHelp.add(mihelp); menubar.add(menuHelp); } // menu bar is complete. setJMenuBar(menubar); // the panel of useful buttons that're part of the non-connective type display JPanel pnonconn = new JPanel(new GridLayout(0, 2)); pnonconn.add(new JButton(acaStrokeThin)); pnonconn.add(new JButton(acaStrokeThick)); pnonconn.add(new JLabel()); pnonconn.add(new JLabel()); pnonconn.add(new JButton(acaSetZonnodes)); pnonconn.add(new JButton(acaUpdateSAreas)); pnonconn.add(new JButton(acaUpdateSymbolLayout)); pnonconn.add(new JButton(acaDetailRender)); pnonconn.add(new JLabel()); pnonconn.add(new JLabel()); pnonconn.add(new JLabel()); pnonconn.add(new JLabel()); pnonconn.add(new JLabel("Connective subtypes")); pnonconn.add(new JButton(acaConntypesymbols)); pnonconn.add(new JButton(acaConntypelabel)); pnonconn.add(new JButton(acaConntypearea)); SetEnabledConnectiveSubtype(false); // we build one of the old tabbing panes into the bottom and have it sketchlinestyle.pthstylenonconn.setLayout(new BorderLayout()); sketchlinestyle.pthstylenonconn.add(pnonconn, BorderLayout.CENTER); sketchlinestyle.pthstylenonconn.add(visiprogressbar, BorderLayout.SOUTH);; // put in the deselect and delete below the row of style buttons Insets inset = new Insets(1, 1, 1, 1); for (int i = 0; i < acPathcomarr.length; i++) { JButton butt = new JButton(acPathcomarr[i]); butt.setMargin(inset); sketchlinestyle.pathcoms.add(butt); } subsetpanel = new SketchSubsetPanel(this); selectedsubsetstruct = new SelectedSubsetStructure(this); backgroundpanel = new SketchBackgroundPanel(this); infopanel = new SketchInfoPanel(this); printingpanel = new SketchPrintPanel(this); secondrender = new SketchSecondRender(this); ztiltpanel = new SketchZTiltPanel(this); if (TN.bTodeNode) todenodepanel = new TodeNodePanel(this); // do the tabbed pane of extra buttons and fields in the side panel. bottabbedpane = new JTabbedPane(); bottabbedpane.addTab("subs", null, subsetpanel, "Subsets used in sketch and on the selected paths"); bottabbedpane.addTab("img", null, backgroundpanel, "Manage the background scanned image used for tracing"); bottabbedpane.addTab("info", null, infopanel, "Inspect the raw information relating to a selected path"); // (sketchdisplay.bottabbedpane.getSelectedIndex() == 2) bottabbedpane.addTab("print", null, printingpanel, "Set resolution for the rendered survey either to a file or to the internet"); bottabbedpane.addTab("view", null, secondrender, "Secondary preview of sketch in a mini-window"); bottabbedpane.addTab("tilt", null, ztiltpanel, "Tilt controls"); if (TN.bTodeNode) { bottabbedpane.addTab("tode", null, todenodepanel, "Neuron experiment"); bottabbedpane.setSelectedIndex(6); } else bottabbedpane.setSelectedIndex(1); bottabbedpane.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent event) { sketchgraphicspanel.UpdateBottTabbedPane(sketchgraphicspanel.currgenpath, sketchgraphicspanel.currselarea, true); } } ); // the full side panel JSplitPane sidepanel = new JSplitPane(JSplitPane.VERTICAL_SPLIT); sidepanel.setLeftComponent(sketchlinestyle); sidepanel.setRightComponent(bottabbedpane); sidepanel.setDividerLocation(300); sketchlinestyle.setMinimumSize(new Dimension(10, 10)); bottabbedpane.setMinimumSize(new Dimension(10, 10)); //JPanel sidepanel = new JPanel(new BorderLayout()); //sidepanel.add(sketchlinestyle, BorderLayout.CENTER); //sidepanel.add(bottabbedpane, BorderLayout.SOUTH); sidepanel.setMinimumSize(new Dimension(10, 10)); JPanel grpanel = new JPanel(new BorderLayout()); grpanel.add(sketchgraphicspanel, BorderLayout.CENTER); // split pane between side panel and graphics area JSplitPane splitPaneG = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); splitPaneG.setDividerLocation(300); splitPaneG.setLeftComponent(sidepanel); splitPaneG.setRightComponent(grpanel); // final set up of display getContentPane().setLayout(new BorderLayout()); getContentPane().add(splitPaneG, BorderLayout.CENTER); addWindowListener(new SketchHide()); pack(); setSize(800, 600); setLocation(300, 100); } ///////////////////////////////////////////// void MakeImages() { Set opselset = sketchgraphicspanel.MakeTotalSelList(); sketchgraphicspanel.UpdateZNodes(); sketchgraphicspanel.UpdateSAreas(); List tvsareas = new ArrayList(); for (OneSArea osa : sketchgraphicspanel.tsketch.vsareas) // vsareas is a sorted set so cannot be indexed { if (osa.iareapressig != SketchLineStyle.ASE_SKETCHFRAME) continue; tvsareas.add(osa); } for (int iosa = tvsareas.size() - 1; iosa >= 0; iosa--) // do in reverse so last one made is first to generate { OneSArea osa = tvsareas.get(iosa); for (int iskop = osa.opsketchframedefs.size() - 1; iskop >= 0; iskop--) // might have same frame generating images at different resolutions { OnePath skop = osa.opsketchframedefs.get(iskop); if (!opselset.isEmpty() && !opselset.contains(skop)) continue; // only do the selected ones if they are selected SketchFrameDef sketchframedef = skop.plabedl.sketchframedef; List losubsets = new ArrayList(); for (String subset : skop.vssubsets) { if (!subset.equals(TN.framestylesubset)) losubsets.add(subset); } if (losubsets.size() == skop.vssubsets.size()) continue; // no framestyle subset listed if (losubsets.size() == 0) losubsets.add(""); // set the outer style for this rendition if (!sketchframedef.sfstyle.equals("")) { int i = subsetpanel.Getcbsubsetstyleindex(sketchframedef.sfstyle); if (i != -1) { SubsetAttrStyle sas = (SubsetAttrStyle)subsetpanel.jcbsubsetstyles.getItemAt(i); subsetpanel.jcbsubsetstyles.setSelectedIndex(i); subsetpanel.SubsetSelectionChanged(true); // needs to be called if done from file menu when the window thread is blocked } } for (int ilosubset = losubsets.size() - 1; ilosubset >= 0; ilosubset--) { String losubset = losubsets.get(ilosubset); System.out.println("llllllllll " + losubset); if (!losubset.equals("")) subsetpanel.SelectSubset(losubset); printingpanel.subsetrect = sketchgraphicspanel.tsketch.getBounds(true, true); printingpanel.UpdatePrintingRectangle(sketchgraphicspanel.tsketch.sketchLocOffset, sketchgraphicspanel.tsketch.realposterpaperscale, true); printingpanel.tfdefaultsavename.setText(losubset); if ((sketchframedef.imagepixelswidth != -1) && (sketchframedef.imagepixelsheight != -1)) { printingpanel.tfpixelswidth.setText(String.valueOf(sketchframedef.imagepixelswidth)); printingpanel.tfpixelsheight.setText(String.valueOf(sketchframedef.imagepixelsheight)); } else if (sketchframedef.imagepixelswidth != -1) { printingpanel.tfpixelswidth.setText(String.valueOf(sketchframedef.imagepixelswidth)); printingpanel.Updatefinalsize(1); } else if (sketchframedef.imagepixelsheight != -1) { printingpanel.tfpixelsheight.setText(String.valueOf(sketchframedef.imagepixelsheight)); printingpanel.Updatefinalsize(2); } printingpanel.OutputIMG("png", 3, true); // 2 for set styles, 3 for everything } } } } ///////////////////////////////////////////// boolean SaveSketch(int savetype) // 0 save, 1 saveas, 2 upload { if (savetype == 1) { FileAbstraction lsketchfile = sketchgraphicspanel.tsketch.sketchfile.SaveAsDialog(SvxFileDialog.FT_XMLSKETCH, sketchgraphicspanel.sketchdisplay, false); if (lsketchfile == null) return false; sketchgraphicspanel.tsketch.sketchfile = lsketchfile; sketchgraphicspanel.tsketch.sketchfile.xfiletype = FileAbstraction.FA_FILE_XML_SKETCH; setTitle("TunnelX - " + sketchgraphicspanel.tsketch.sketchfile.getPath()); } if (savetype == 2) { String target = TN.troggleurl + "jgtuploadfile"; // for now FileAbstraction uploadedimage = NetConnection.uploadFile(FileAbstraction.MakeOpenableFileAbstraction(target), "sketch", sketchgraphicspanel.tsketch.sketchfile.getSketchName() + ".xml", null, sketchgraphicspanel.tsketch); if (uploadedimage == null) return TN.emitWarning("bum"); TN.emitMessage("jjj " + uploadedimage.getPath()); FileAbstraction lsketchfile = FileAbstraction.GetImageFile(null, TN.setSuffix(uploadedimage.getPath(), TN.SUFF_XML)); if (lsketchfile == null) return false; sketchgraphicspanel.tsketch.sketchfile = lsketchfile; setTitle("TunnelX - " + sketchgraphicspanel.tsketch.sketchfile.getPath()); mainbox.tunnelfilelist.tflist.repaint(); return true; } visiprogressbar.setString("saving"); visiprogressbar.setStringPainted(true); visiprogressbar.setValue(80); sketchgraphicspanel.tsketch.SaveSketch(); visiprogressbar.setStringPainted(false); visiprogressbar.setValue(0); mainbox.tunnelfilelist.tflist.repaint(); return true; } ///////////////////////////////////////////// // switched on and off if we have a connective line selected void SetEnabledConnectiveSubtype(boolean benabled) { acaConntypesymbols.setEnabled(benabled); acaConntypelabel.setEnabled(benabled); acaConntypearea.setEnabled(benabled); } ///////////////////////////////////////////// void ApplySplineChange(boolean lbHideSplines) { OnePath.bHideSplines = lbHideSplines; for (OneSketch tsketch : mainbox.ftsketches) { if (tsketch.bsketchfileloaded) tsketch.ApplySplineChange(); } for (OneSketch tsketch : mainbox.vgsymbolstsketches) { if (tsketch.bsketchfileloaded) tsketch.ApplySplineChange(); } } ///////////////////////////////////////////// void ActivateSketchDisplay(OneSketch activesketch, boolean lbEditable) { sketchgraphicspanel.bEditable = lbEditable; sketchgraphicspanel.ClearSelection(true); sketchgraphicspanel.tsketch = activesketch; sketchgraphicspanel.asketchavglast = null; // used for lazy evaluation of the average transform. // set greyness acaUpdateSAreas.setEnabled(!sketchgraphicspanel.tsketch.bSAreasUpdated); acaUpdateSymbolLayout.setEnabled(!sketchgraphicspanel.tsketch.bSymbolLayoutUpdated); // set the transform pointers to same object setTitle(activesketch.sketchfile.getPath()); // it's confusing if this applies to different views if (!miThinZheightsel.isSelected()) miThinZheightsel.setSelected(false); // could record the last viewing position of the sketch; saved in the sketch as an affine transform sketchgraphicspanel.MaxAction(2); // maximize sketchgraphicspanel.UpdateBottTabbedPane(null, null, true); String sfstyle = ""; // quick and dirty hunt for what you might want as the default if (sketchgraphicspanel.tsketch.sksascurrent == null) { int isfstylescore = 0; for (OnePath op : sketchgraphicspanel.tsketch.vpaths) { int lisfstylescore = 2; if (op.IsSketchFrameConnective() && !op.plabedl.sketchframedef.sfstyle.equals("")) { if (op.plabedl.sketchframedef.sfsketch.equals("") || op.plabedl.sketchframedef.IsImageType()) lisfstylescore = 3; for (String subset : op.vssubsets) { if (subset.equals(TN.framestylesubset)) lisfstylescore = 4; } if (lisfstylescore >= isfstylescore) { sfstyle = op.plabedl.sketchframedef.sfstyle; isfstylescore = lisfstylescore; } } if (op.IsSurvexLabel()) { if ((subsetpanel.jcbsubsetstyles.getItemCount() != 0) && (isfstylescore == 0)) { sfstyle = ((SubsetAttrStyle)subsetpanel.jcbsubsetstyles.getItemAt(0)).stylename; isfstylescore = 1; } } } TN.emitMessage("Choosing default sfstyle: "+sfstyle); } else { sfstyle = sketchgraphicspanel.tsketch.sksascurrent.stylename; TN.emitMessage("Resetting previous sfstyle: "+sfstyle); } subsetpanel.SetSubsetStyleFromString(sfstyle); printingpanel.ResetDIR((TN.currprintdir == null)); // catch it here infopanel.searchlistmodel.clear(); toFront(); setVisible(true); sketchgraphicspanel.repaint(); } ///////////////////////////////////////////// void ReloadFontcolours() { FileAbstraction.imagefiledirectories.clear(); SketchLineStyle.nareasignames = 0; sketchlinestyle.subsetattrstylesmap.clear(); sketchlinestyle.bsubsetattributesneedupdating = true; for (FileAbstraction tfile : mainbox.allfontcolours) mainbox.tunnelloader.LoadFontcolour(tfile); if (sketchlinestyle.bsubsetattributesneedupdating) sketchlinestyle.UpdateSymbols(false); if (sketchgraphicspanel.tsketch != null) SketchGraphics.SketchChangedStatic(SketchGraphics.SC_CHANGE_SAS, sketchgraphicspanel.tsketch, this); mainbox.tunnelfilelist.tflist.repaint(); miUseSurvex.setSelected(FileAbstraction.SurvexExists()); } ///////////////////////////////////////////// boolean ImportAtlasTemplate() { AtlasGenerator ag = new AtlasGenerator(); OneSketch asketch = mainbox.tunnelfilelist.GetSelectedSketchLoad(); if (asketch == null) return TN.emitWarning("No Sketch selected in mainbox which to use as the atlas template for duplicating into current sketch"); if (asketch.sksascurrent == null) asketch.SetSubsetAttrStyle(sketchgraphicspanel.tsketch.sksascurrent, null); asketch.UpdateSomething(SketchGraphics.SC_UPDATE_ZNODES, true); asketch.UpdateSomething(SketchGraphics.SC_UPDATE_AREAS, true); mainbox.UpdateSketchFrames(asketch, SketchGraphics.SC_UPDATE_ALL_BUT_SYMBOLS); ag.ImportAtlasTemplate(asketch); List pthstoadd = new ArrayList(); pthstoadd.addAll(ag.vpathsatlas); sketchgraphicspanel.CommitPathChanges(null, pthstoadd); sketchgraphicspanel.UpdateBottTabbedPane(null, null, true); subsetpanel.SubsetSelectionChanged(true); sketchgraphicspanel.MaxAction(2); // maximize return true; } ///////////////////////////////////////////// boolean ImportSketchCentrelineFile(SvxFileDialog sfiledialog) { OnePath optext; if (sketchgraphicspanel.currgenpath == null) { List pthstoadd = new ArrayList(); optext = sketchgraphicspanel.MakeConnectiveLineForData(1, TN.radiusofsurveylabel_S); pthstoadd.add(optext); sketchgraphicspanel.CommitPathChanges(null, pthstoadd); // selects } else { sketchlinestyle.GoSetParametersCurrPath(); optext = sketchgraphicspanel.currgenpath; } if (!sketchgraphicspanel.bEditable || (optext == null) || (optext.linestyle != SketchLineStyle.SLS_CONNECTIVE) || (optext.plabedl == null) || optext.plabedl.sfontcode.equals("")) return TN.emitWarning("Connective Path with label must be created or selected"); if (sfiledialog == null) { sfiledialog = SvxFileDialog.showOpenDialog(TN.currentDirectory, this, SvxFileDialog.FT_SVX, false); if ((sfiledialog == null) || ((sfiledialog.svxfile == null) && (sfiledialog.tunneldirectory == null))) return false; // was all made complicated and broken because of ability to save and rewrite the name of file if .xml left off it FileAbstraction fa = sfiledialog.svxfile; // sfiledialog.getSelectedFileA(SvxFileDialog.FT_SVX, false); if (fa.localurl == null) TN.currentDirectory = fa; TN.emitMessage(sfiledialog.svxfile.toString() + " CD " + TN.currentDirectory.getAbsolutePath() + " " + (fa.localurl == null)); } String survextext = null; if (sfiledialog.svxfile.xfiletype == FileAbstraction.FA_FILE_SVX) survextext = (new SurvexLoaderNew()).LoadSVX(sfiledialog.svxfile); else if (sfiledialog.svxfile.xfiletype == FileAbstraction.FA_FILE_POCKET_TOPO) { PocketTopoLoader ptl = new PocketTopoLoader(); ptl.LoadPockettopo(sfiledialog.svxfile); survextext = ptl.GetSVX(); sketchgraphicspanel.CommitPathChanges(null, ptl.vpathsplan); } else if (sfiledialog.svxfile.xfiletype == FileAbstraction.FA_FILE_POCKET_BINTOP) { TunnelTopParser tunnTOP = new TunnelTopParser(); tunnTOP.ParseTOPFile(sfiledialog.svxfile); survextext = tunnTOP.GetSVX(); for (OnePath op : tunnTOP.vpathsplan) op.vssubsets.add(TN.planCLINEsubset); sketchgraphicspanel.CommitPathChanges(null, tunnTOP.vpathsplan); for (OnePath op : tunnTOP.vpathselev) op.vssubsets.add(TN.elevCLINEsubset); sketchgraphicspanel.CommitPathChanges(null, tunnTOP.vpathselev); optext.vssubsets.add(TN.planCLINEsubset); optext.vssubsets.add(TN.elevCLINEsubset); } else TN.emitError("unknown file type loader " + sfiledialog.svxfile.xfiletype); // select and apply the svx text sketchgraphicspanel.SelectSingle(optext); // selects sketchlinestyle.pthstylelabeltab.labtextfield.setText(survextext); // the document events and the window copies it into optext if (sfiledialog == null) sketchgraphicspanel.MaxAction(2); // maximize else System.out.println("not doing maxaction"); return true; } ///////////////////////////////////////////// boolean ImportCentrelineLabel(String scommand) { TN.emitMessage("ImportCentrelineLabel scommand="+scommand); boolean bpreview = scommand.equals("preview"); // switch off survex if tmp not available if (miUseSurvex.isSelected() && !FileAbstraction.tmpdir.isDirectory()) { // why isn't this working? TN.emitWarning("Cannot run survex without tunnelx/tmp directory"); TN.emitWarning("Switching off Import | Use Survex flag"); miUseSurvex.setEnabled(false); } boolean btopextendedelevation = scommand.equals("TOPelevation"); boolean busesurvex = !scommand.equals("nosurvex") && !btopextendedelevation && miUseSurvex.isSelected(); OnePath opcll = sketchgraphicspanel.currgenpath; if ((opcll == null) || !opcll.IsSurvexLabel()) { // don't use tspathssurvexlabel as may be out of date when making new sketch for (OnePath op : sketchgraphicspanel.tsketch.vpaths) { if (op.IsSurvexLabel()) opcll = op; } } if ((opcll == null) || !opcll.IsSurvexLabel()) return !TN.emitWarning("Connective Path with label containing the survex data must be selected"); boolean bplancase = opcll.vssubsets.contains(TN.planCLINEsubset); boolean belevcase = opcll.vssubsets.contains(TN.elevCLINEsubset); // load in the centreline we have into the sketch // could even check with centreline existing // this is how we do the extending of centrelines // if (!bpreview && !sketchgraphicspanel.tsketch.sketchLocOffset.isZero()) // return !TN.emitWarning("Sketch Loc Offset already set; pos already have loaded in a centreline"); // set to null (for the purpose of resetting) only if not set already and there are no non-connective paths already drawn Vec3 appsketchLocOffset = sketchgraphicspanel.tsketch.sketchLocOffset; if (sketchgraphicspanel.tsketch.sketchLocOffset.isZero()) { int nnonconnectivepaths = 0; for (OnePath op : sketchgraphicspanel.tsketch.vpaths) { if (op.linestyle != SketchLineStyle.SLS_CONNECTIVE) nnonconnectivepaths++; } if (nnonconnectivepaths == 0) appsketchLocOffset = null; } // run survex cases SurvexLoaderNew sln = null; if (!bpreview || !busesurvex) { sln = new SurvexLoaderNew(); sln.btopextendedelevation = btopextendedelevation; sln.InterpretSvxText(opcll.plabedl.drawlab); } if (busesurvex) // copy in the POS files { if (!FileAbstraction.RunSurvex(sln, opcll.plabedl.drawlab, appsketchLocOffset, bpreview)) return false; if (bpreview) return true; } else { TN.emitWarning("Not using Survex, so no distributing of loop closure errors"); sln.sketchLocOffset = (appsketchLocOffset == null ? new Vec3d((float)sln.avgfix.x, (float)sln.avgfix.y, (float)sln.avgfix.z) : new Vec3d((float)appsketchLocOffset.x, (float)appsketchLocOffset.y, (float)appsketchLocOffset.z)); sln.CalcStationPositions(); } if (bpreview) // show preview { mainbox.wireframedisplay.wiregraphicspanel.vlegs.clear(); mainbox.wireframedisplay.wiregraphicspanel.vstations.clear(); sln.ConstructWireframe(mainbox.wireframedisplay.wiregraphicspanel.vlegs, mainbox.wireframedisplay.wiregraphicspanel.vstations); mainbox.wireframedisplay.ActivateWireframeDisplay("Name of sketch"); return true; } sketchgraphicspanel.ClearSelection(true); // set the Locoffset if (appsketchLocOffset == null) sketchgraphicspanel.tsketch.sketchLocOffset = new Vec3((float)sln.sketchLocOffset.x, (float)sln.sketchLocOffset.y, (float)sln.sketchLocOffset.z); else assert Math.abs(appsketchLocOffset.x - sketchgraphicspanel.tsketch.sketchLocOffset.x) < 0.000001; // do anaglyph rotation here // TransformSpaceToSketch tsts = new TransformSpaceToSketch(currgenpath, sketchdisplay.mainbox.sc); // statpathnode[ipns] = tsts.TransPoint(ol.osfrom.Loc); Vec3 xrot, yrot, zrot; double rotanaglyph = 0.0; // hard code this and recompile before reimporting //double rotanaglyph = -5.0 * Math.PI / 180; // hard code this and recompile before reimporting if (sln.bprojectedelevation) { double th = sln.projectedelevationvalue * Math.PI / 180; xrot = new Vec3((float)Math.cos(th), (float)Math.sin(th), 0.0F); yrot = new Vec3(0.0F, 0.0F, 1.0F); zrot = new Vec3(-(float)Math.sin(th), (float)Math.cos(th), 0.0F); TN.emitWarning("\n\n\n*****\n*****elevation rotation th " + th + "\n*****\n\n\n"); } else if (rotanaglyph != 0.0) { double cs = Math.cos(rotanaglyph); double sn = Math.sin(rotanaglyph); xrot = new Vec3((float)cs, 0.0F, (float)sn); yrot = new Vec3(0.0F, 1.0F, 0.0F); zrot = new Vec3(-(float)sn, 0.0F, (float)cs); TN.emitWarning("\n\n\n*****\n*****anaglyph rot sn " + sn + "\n*****\n\n\n"); } else { xrot = new Vec3(1.0F, 0.0F, 0.0F); yrot = new Vec3(0.0F, 1.0F, 0.0F); zrot = new Vec3(0.0F, 0.0F, 1.0F); } Vec3 fsketchLocOffset = new Vec3((float)sln.sketchLocOffset.x, (float)sln.sketchLocOffset.y, (float)sln.sketchLocOffset.z); sketchgraphicspanel.tsketch.sketchLocOffset = new Vec3(fsketchLocOffset.Dot(xrot), fsketchLocOffset.Dot(yrot), fsketchLocOffset.Dot(zrot)); double xsmin = 0.0; double ysmin = 0.0; boolean bfirstsmin = true; List vstations = new ArrayList(); for (OneStation os : sln.osmap.values()) { if (os.station_opn == null) { vstations.add(os); assert os.Loc != null; os.station_opn = new OnePathNode(os.Loc.Dot(xrot) * TN.CENTRELINE_MAGNIFICATION, -os.Loc.Dot(yrot) * TN.CENTRELINE_MAGNIFICATION, os.Loc.Dot(zrot) * TN.CENTRELINE_MAGNIFICATION); xsmin = (bfirstsmin ? os.station_opn.pn.getX() : Math.min(os.station_opn.pn.getX(), xsmin)); ysmin = (bfirstsmin ? os.station_opn.pn.getY() : Math.min(os.station_opn.pn.getY(), ysmin)); bfirstsmin = false; } } if (!btopextendedelevation) { if (!sln.ThinDuplicateLegs(sketchgraphicspanel.tsketch.vnodes, sketchgraphicspanel.tsketch.vpaths)) return TN.emitWarning("Cannot copy over extended legs"); } boolean bcopytitles = miImportTitleSubsets.isSelected(); boolean bcopydates = miImportDateSubsets.isSelected(); int Dnsurfacelegs = 0; int Dnfixlegs = 0; List pthstoadd = new ArrayList(); List pthstoremove = new ArrayList(); // perform the translation of the "S" { double vx = xsmin - opcll.pnstart.pn.getX(); double vy = ysmin - opcll.pnend.pn.getY(); OnePathNode nopnstart = new OnePathNode((float)(opcll.pnstart.pn.getX() + vx), (float)(opcll.pnstart.pn.getY() + vy), opcll.pnstart.zalt); OnePathNode nopnend = new OnePathNode((float)(opcll.pnend.pn.getX() + vx), (float)(opcll.pnend.pn.getY() + vy), opcll.pnend.zalt); float[] pco = opcll.GetCoords(); OnePath nopcll = new OnePath(nopnstart); for (int i = 1; i < opcll.nlines; i++) nopcll.LineTo((float)(pco[i * 2] + vx), (float)(pco[i * 2 + 1] + vy)); nopcll.EndPath(nopnend); nopcll.CopyPathAttributes(opcll); pthstoremove.add(opcll); pthstoadd.add(nopcll); } // add in all the legs to the adding section for (OneLeg ol : sln.vlegs) { if (ol.osfrom == null) Dnfixlegs++; else if (ol.bsurfaceleg) Dnsurfacelegs++; else { OnePath lop = new OnePath(ol.osfrom.station_opn, ol.osfrom.name, ol.osto.station_opn, ol.osto.name); if (bcopytitles && !ol.svxtitle.equals("")) lop.vssubsets.add(ol.svxtitle); if (bcopydates && !ol.svxdate.equals("")) lop.vssubsets.add("__date__ " + ol.svxdate.substring(0, 4)); if (bplancase || belevcase) lop.vssubsets.add(btopextendedelevation ? TN.elevCLINEsubset : TN.planCLINEsubset); pthstoadd.add(lop); } } TN.emitMessage("Ignoring " + Dnfixlegs + " fixlegs and " + Dnsurfacelegs + " surfacelegs"); sketchgraphicspanel.asketchavglast = null; // change of avg transform cache. sketchgraphicspanel.CommitPathChanges(pthstoremove, pthstoadd); // check everything has been designated centreline nodes after the above commit for (OneLeg ol : sln.vlegs) { if (!ol.bsurfaceleg) { assert ((ol.osfrom == null) || ol.osfrom.station_opn.IsCentrelineNode()); assert (ol.osto.station_opn.IsCentrelineNode()); } } //subsetpanel.SubsetSelectionChanged(true); return true; } } tunnelx-20140102.orig/src/SvgGraphics2D.java0000644000000000000000000002643012261213471015333 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.Shape; import java.awt.geom.Area; import java.awt.Color; import java.awt.BasicStroke; import java.awt.Stroke; import java.awt.Font; import java.awt.geom.AffineTransform; import java.awt.geom.PathIterator; import java.io.IOException; import java.util.ArrayList; import java.util.List; // refer to // http://www.w3.org/TR/SVG/style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1".html#PathElement // need to know about inheritance of attributes (colour, stroke style) // to save on repetition // need to know about filling and blending, to save the repeat list for each polygon // (once with a white shade, once with the colour) // need to put out the fonts and labels // need to get the window to be setable. // need to shift the whole picture close to origin to avoid repeating // numbers with the same digits. // need to get symbols drawn as part of subroutine objects so they don't need // to be respecified each time. // these measures should help to get a very compact file that can be used // on the CUCC webpage for the surveys. // SVG gives possibility of highlighting different areas as the mouse passes // over them or their labels, and linking to descriptions, or descriptions // going to views on the svg, animating-wise. // I(JGT)'ve got other stuff to code with the subsets and loading efficiency. // Someone else could easily become an SVG expert and take this over, // as it's reasonably self-contained and I know nothing about it. // SVG output is called by selecting File | Export J-SVG // and it writes a file called "ssvg.svg" in your tunnel directory. // The only commands that I use to make the image are in this // file; but we can easily upgrade it and add extra signals so // that it can stream out extra signals to help it make the // commands that will respond to the mouse dynamically. // There are many resources on the web with SVG examples. // It easily has all the power of flash, and can do everything // you can imagine for stuff to happen in 2D. // The point of doing it like this rather than using a general // purpose library is that we can tune it to exactly the way // Tunnel uses it (or change the way Tunnel renders its // graphics to make it more appropriate for this) and so // generate relatively short, dense files. // we could batch up the objects using convd or by tracking them themselves // and look for duplicates and use the type to // print them twice with the different styles public class SvgGraphics2D extends Graphics2Dadapter // instead of Graphics2D because all the abstract functions that need to be overridden { Shape clip = null; private LineOutputStream los; // don't write to this until the end private StringBuffer defs = new StringBuffer(); private StringBuffer premain = new StringBuffer(); private StringBuffer main = new StringBuffer(); private Font currfont; private int cpcount = 0; // to generate unique ID's for clipping paths private float xoffset, yoffset; private SvgPathStyleTracker myPST; Area totalarea = null; String backmaskcol = null; SvgGraphics2D(LineOutputStream llos, String lbackmaskcol) { if (lbackmaskcol != null) { totalarea = new Area(); backmaskcol = lbackmaskcol; } los = llos; myPST = new SvgPathStyleTracker(); } // open and close void writeheader(float x, float y, float width, float height, float scalefactor) throws IOException { TNXML.chconvleng = TNXML.chconvlengWSP; // a complete hack to stop &space; getting in here float widthmm = (width / TN.CENTRELINE_MAGNIFICATION) / scalefactor * 1000; float heightmm = (height / TN.CENTRELINE_MAGNIFICATION) / scalefactor * 1000; TN.emitMessage("Scalefactor " + scalefactor + " paperwidth="+widthmm +"mm paperheight="+heightmm +"mm"); xoffset = x; yoffset = y; los.WriteLine("\n"); los.WriteLine(""); String viewbox = "0 0 " + String.valueOf(width) + " " + String.valueOf(height); los.WriteLine(TNXML.xcomopen(0, "svg", "width", Float.toString(widthmm) + "mm", "height", Float.toString(heightmm) + "mm", "viewBox", viewbox, "xmlns", "http://www.w3.org/2000/svg", "version", "1.1")); los.WriteLine(TNXML.xcomtext(1, "title", "Example")); los.WriteLine(TNXML.xcomtext(1, "desc", "description thing")); los.WriteLine(TNXML.xcom(1, "rect", "x", "0", "y", "0", "width", String.valueOf(width), "height", String.valueOf(height), "fill", "none", "stroke", "blue")); } void writefooter() throws IOException // misnomer now; it doesn't just write the footer { if (backmaskcol != null) { float strokewidthpt = 4.0F; String style = String.format("stroke: %s; stroke-width: %.1fpx; stroke-linecap: round; stroke-linejoin: round; fill: %s; fill-opacity: 1.0", backmaskcol, strokewidthpt, backmaskcol); writeshape(totalarea, style, premain); } los.WriteLine(TNXML.xcomopen(0,"defs")); los.Write(defs.toString()); los.WriteLine(TNXML.xcomopen(0, "style", "type", "text/css") + "" + TNXML.xcomclose(0, "style")); los.WriteLine(TNXML.xcomclose(0, "defs")); if (backmaskcol != null) { los.WriteLine(TNXML.xcomopen(0, "g", "id", "backmask")); los.Write(premain.toString()); los.WriteLine(TNXML.xcomclose(0, "g")); } los.WriteLine(TNXML.xcomopen(0, "g", "id", "main")); los.Write(main.toString()); // writeUTF? los.WriteLine(TNXML.xcomclose(0, "g")); los.WriteLine(TNXML.xcomclose(0, "svg")); TNXML.chconvleng = TNXML.chconvCH.length; } public void setColor(Color c) { int rgb = c.getRGB(); myPST.crgb = String.format("#%06x", Integer.valueOf(rgb & 0xffffff)); myPST.calpha = ((rgb >> 24) & 255) / 255.0F; } public void setStroke(Stroke s) { BasicStroke bs = (BasicStroke)s; myPST.strokewidth = bs.getLineWidth(); } public void setFont(Font f) { //System.out.println(String.format("Setting font %s %f", f.getFamily(), f.getSize2D())); myPST.currfont = f; } public void drawString(String s, float x, float y) { String style = myPST.stringifyText(); String sclass = myPST.getClassName(style); main.append(TNXML.xcomopen(0, "text", "x", String.format("%.1f", x - xoffset), "y", String.format("%.1f", y - yoffset), "class", sclass)); TNXML.xmanglxmltextSB(main, s, false); main.append(TNXML.xcomclose(0, "text")); main.append("\n"); } public void draw(Shape s) { writeshape(s, myPST.stringifyOutline(), main); } public void fill(Shape s) { writeshape(s, myPST.stringifyFill(), main); if ((backmaskcol != null) && s.getClass().getName().equals("java.awt.geom.Area")) totalarea.add((Area)s); } public void clip(Shape lclip) { setClip(lclip); // quick make work } public void setClip(Shape lclip) { if (lclip != null) { clip = null; // don't want clipping path itself to be clipped! defs.append(TNXML.xcomopen(0, "clipPath", "id", "cp" + Integer.toString(++cpcount))+"\n"); writeshape(lclip, null, defs); defs.append(TNXML.xcomclose(0, "clipPath")+"\n"); } clip = lclip; } public Shape getClip() { return clip; } //////////////////////////////////////// String dconv(Shape s) { StringBuffer sb = new StringBuffer(); PathIterator it = s.getPathIterator(null); while (!it.isDone()) { int type = it.currentSegment(coords); if (type == PathIterator.SEG_MOVETO) { sb.append("M"); sb.append(String.format("%.1f %.1f", coords[0] - xoffset, coords[1] - yoffset)); } else if (type == PathIterator.SEG_CLOSE) { sb.append(" Z"); } else if (type == PathIterator.SEG_LINETO) { sb.append(" L"); sb.append(String.format("%.1f %.1f", coords[0] - xoffset, coords[1] - yoffset)); } else if (type == PathIterator.SEG_CUBICTO) { sb.append(" C"); sb.append(String.format("%.1f %.1f", coords[0] - xoffset, coords[1] - yoffset)); sb.append(String.format(" %.1f %.1f", coords[2] - xoffset, coords[3] - yoffset)); sb.append(String.format(" %.1f %.1f", coords[4] - xoffset, coords[5] - yoffset)); } it.next(); } return sb.toString(); } //////////////////////////////////////// // static float[] coords = new float[6]; private void writeshape(Shape s, String style, StringBuffer dest) { dest.append("\n"); } } class SvgPathStyleTracker { public String crgb; public float calpha; public float strokewidth; public Font currfont; private List stylestack; SvgPathStyleTracker() { stylestack = new ArrayList(); } String stringifyFill() { return String.format("stroke: none; fill: %s; fill-opacity: %f", crgb, calpha); } String stringifyOutline() { return String.format("stroke: %s; stroke-width: %.1fpx; stroke-linecap: round; fill: none", crgb, strokewidth); } String stringifyText() { if (currfont == null) { System.out.println("Using null font!"); return "XXX"; } String fontfamily = currfont.getFamily(); return String.format("font-family: %s; font-size: %.1fpx; font-style: %s; font-weight: %s; fill: %s", fontfamily, currfont.getSize2D(), (currfont.isItalic() ? "italic" : "normal"), (currfont.isBold() ? "bold" : "normal"), crgb); } public String getClassName(String currstyle) { int n = stylestack.indexOf(currstyle); if (n == -1) { n = stylestack.size(); stylestack.add(currstyle); } return "c" + String.valueOf(n); } public String dumpStyles() { StringBuffer s = new StringBuffer(""); for(int i = 0; i < stylestack.size(); i++) { s.append(String.format(".c%d\t{ %s }\n", i, stylestack.get(i))); } return s.toString(); } } tunnelx-20140102.orig/src/FileAbstraction.java0000644000000000000000000014250012261213471015773 0ustar //////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.io.IOException; import java.io.FileNotFoundException; import java.io.BufferedReader; import java.io.InputStream; import java.io.FileInputStream; import java.io.FileReader; import java.io.File; import java.io.StringReader; import java.io.InputStreamReader; import java.io.DataOutputStream; import java.net.URLClassLoader; import java.net.URL; import java.net.URLConnection; import java.net.MalformedURLException; import java.util.List; import java.util.ArrayList; import java.util.Collections; import java.util.Collection; import java.util.Arrays; import java.util.Comparator; //import java.util.regexp.Pattern; // does not exist import java.awt.Image; import java.awt.image.BufferedImage; import javax.imageio.ImageIO; import javax.swing.JFrame; import java.util.regex.Matcher; import java.util.regex.Pattern; // // // FileAbstraction // // ///////////////////////////////////////////// // we can gradually move all the file name generating and handling code into this class, // and then arrange to share the work with what's going on on the server. // Only return linein/outputstreams to these. ///////////////////////////////////////////// // general function which will handle getting files from the local computer // and from the internet public class FileAbstraction { // single type files (per OneTunnel) static int FA_FILE_UNKNOWN = 0; static int FA_FILE_XML_MEASUREMENTS = 1; static int FA_FILE_XML_EXPORTS = 2; static int FA_FILE_SVX = 3; static int FA_FILE_POS = 4; static int FA_FILE_3D = 5; // multiple files possible static int FA_FILE_XML_SKETCH = 6; static int FA_FILE_XML_FONTCOLOURS = 7; static int FA_FILE_IMAGE = 8; static int FA_FILE_IGNORE = 9; static int FA_DIRECTORY = 10; static int FA_FILE_POCKET_TOPO = 11; static int FA_FILE_HTML = 12; static int FA_FILE_POCKET_BINTOP = 13; static int FA_FILE_SVG = 14; static int FA_FILE_PDF = 15; // default type, because starting in the static main of MainBox allows us to set to false static boolean bIsApplet = true; static boolean bIsUnixSystem = System.getProperty("file.separator").equals("/"); // the actual File localfile; URL localurl; boolean bIsDirType = false; int xfiletype; static FileAbstraction currentSymbols = new FileAbstraction(); static FileAbstraction helpFile = new FileAbstraction(); static FileAbstraction tutorialSketches = new FileAbstraction(); static File tmpdir = null; static void InitFA() { ClassLoader cl = MainBox.class.getClassLoader(); currentSymbols = new FileAbstraction(); currentSymbols.bIsDirType = true; currentSymbols.xfiletype = FA_DIRECTORY; tmpdir = null; tutorialSketches = new FileAbstraction(); tutorialSketches.bIsDirType = true; tutorialSketches.xfiletype = FA_DIRECTORY; if (!bIsApplet) { File ldir = new File(System.getProperty("user.dir"), "symbols"); if (bIsUnixSystem) { if (!ldir.isDirectory()) ldir = new File(System.getProperty("user.home"), ".tunnelx/symbols/"); if (!ldir.isDirectory()) ldir = new File("/usr/share/tunnelx/symbols/"); } else { if (!ldir.isDirectory()) ldir = new File(System.getProperty("user.home"), "symbols"); } if (ldir.isDirectory()) currentSymbols.localfile = ldir; tmpdir = new File(System.getProperty("user.dir"), "tmp"); if (!tmpdir.isDirectory() && bIsUnixSystem) tmpdir = new File(System.getProperty("user.home"), ".tunnelx/tmp/"); if (!tmpdir.isDirectory()) tmpdir = new File(System.getProperty("java.io.tmpdir")); if (!tmpdir.isDirectory()) tmpdir = null; } // instead get from jar file (if we're in one) if (currentSymbols.localfile == null) { currentSymbols.localurl = cl.getResource("symbols/"); if (currentSymbols.localurl == null) currentSymbols.localurl = cl.getResource("symbols/listdir.txt"); // this gets it from the jar file } if (tutorialSketches.localfile == null) { tutorialSketches.localurl = cl.getResource("tutorials/"); if (tutorialSketches.localurl == null) tutorialSketches.localurl = cl.getResource("tutorials/listdir.txt"); // this gets it from the jar file } // the useful help file always pull from jar file helpFile.localurl = cl.getResource("symbols/helpfile.html"); if (helpFile.localurl == null) TN.emitWarning("Missing symbols/helpfile.html"); if ((TN.tunneluser == null) || TN.tunneluser.equals("")) TN.tunneluser = System.getProperty("user.name"); TN.emitMessage(""); TN.emitMessage("currentSymbols: " + FileAbstraction.currentSymbols.getAbsolutePath()); TN.emitMessage("tutorials: " + FileAbstraction.tutorialSketches.getAbsolutePath()); TN.emitMessage("helpfile: " + FileAbstraction.helpFile.getAbsolutePath()); TN.emitMessage("tmpdir: " + FileAbstraction.tmpdir.getAbsolutePath()); TN.emitMessage("tunnelversion: " + TN.tunnelversion); TN.emitMessage("tunneluser: " + TN.tunneluser); TN.emitMessage(""); } // start easy by putting all the constructors FileAbstraction() { localfile = null; localurl = null; } String getName() { if (localurl != null) { // applet case; strip off slashes and trailing slashes for dirs String res = localurl.getPath(); int lch = (res.charAt(res.length() - 1) == '/' ? res.length() - 1 : res.length()); int i = res.lastIndexOf("/", lch - 1); if (i == -1) return res.substring(0, lch); if ((currentSymbols.xfiletype == FA_DIRECTORY) && res.substring(i + 1, lch).equals("listdir.txt")) { lch = i; i = res.lastIndexOf("/", lch - 1); } return res.substring(i + 1, lch); } assert !bIsApplet; return localfile.getName(); } String getSketchName() { String sname = getName(); if (xfiletype == FA_FILE_XML_SKETCH) { assert sname.substring(sname.length() - 4).equalsIgnoreCase(".xml"); return sname.substring(0, sname.length() - 4); } else if (xfiletype == FA_FILE_SVX) { assert sname.substring(sname.length() - 4).equalsIgnoreCase(".svx"); return sname.substring(0, sname.length() - 4); } else if (xfiletype == FA_FILE_POCKET_TOPO) { if ((sname.length() > 12) && (sname.substring(sname.length() - 12).equalsIgnoreCase("-therion.txt"))) return sname.substring(0, sname.length() - 12); assert sname.substring(sname.length() - 4).equalsIgnoreCase(".txt"); return sname.substring(0, sname.length() - 4); } else if (xfiletype == FA_FILE_POCKET_BINTOP) { assert sname.substring(sname.length() - 4).equalsIgnoreCase(".top"); return sname.substring(0, sname.length() - 4); } TN.emitError("file " + sname + " has wrong type: " + xfiletype); return sname; } String getPath() { return (localurl != null ? localurl.toString() : localfile.getPath()); } String getAbsolutePath() { assert !bIsApplet; if (localfile != null) return localfile.getAbsolutePath(); if (localurl != null) return localurl.toString(); return null; } String getCanonicalPath() throws IOException { assert !bIsApplet; return localfile.getCanonicalPath(); } FileAbstraction getParentFile() { if (bIsApplet) return null; if (localfile != null) { String parent = localfile.getParent(); if (parent == null) return null; return MakeDirectoryFileAbstraction(parent); } if (localurl.getPath().equals("/") || localurl.getPath().equals("")) return null; try { FileAbstraction faf = new FileAbstraction(); faf.localurl = new URL(localurl, ".."); return faf; } catch (MalformedURLException e) { return null; } } boolean isDirectory() { assert !bIsApplet; if (localurl == null) return localfile.isDirectory(); String urlname = localurl.getPath(); return ((urlname.indexOf("/tunneldata") != -1) && (urlname.indexOf(".xml") == -1)); } boolean isFile() { assert !bIsApplet; assert localfile != null; return localfile.isFile(); } boolean equals(FileAbstraction fa) { if ((localurl != null) && (fa.localurl != null)) return localurl.equals(fa.localurl); if ((localfile == null) || (fa.localfile == null)) return false; assert !bIsApplet; return localfile.equals(fa.localfile); } // this is killed (except for debug) public String toString() { //assert false; if (localfile != null) return localfile.toString(); if (localurl != null) return localurl.toString(); return "null"; } ///////////////////////////////////////////// static FileAbstraction MakeOpenableFileAbstraction(String fname) { assert !bIsApplet; FileAbstraction res = new FileAbstraction(); res.bIsDirType = false; int ijar = fname.indexOf("jarresource:"); int ihttp = fname.indexOf("http:"); if (ihttp != -1) { ihttp += 5; while ((ihttp < fname.length()) && ((fname.charAt(ihttp) == '\\') || (fname.charAt(ihttp) == '/'))) ihttp++; String utail = fname.substring(ihttp).replace('\\', '/'); TN.emitMessage("UUUUUUU " + utail); try { res.localurl = new URL("http://" + utail); } catch (MalformedURLException e) { TN.emitWarning("yyy");} if (res.localurl == null) return null; } else if (ijar != -1) { TN.emitMessage("doing jarresource of: "+fname); String jresource = fname.substring(ijar+12).replace('!', '/'); ClassLoader cl = MainBox.class.getClassLoader(); res.localurl = cl.getResource(jresource); if (res.localurl == null) TN.emitError("Resource "+jresource+" not found in jar file"); } else res.localfile = new File(fname); return res; } ///////////////////////////////////////////// static FileAbstraction MakeWritableFileAbstractionF(File file) { assert !bIsApplet; FileAbstraction res = new FileAbstraction(); res.localfile = file; res.bIsDirType = false; return res; } ///////////////////////////////////////////// static FileAbstraction MakeWritableFileAbstraction(String fname) { assert !bIsApplet; FileAbstraction res = new FileAbstraction(); res.localfile = new File(fname); res.bIsDirType = false; return res; } ///////////////////////////////////////////// static FileAbstraction MakeOpenableFileAbstractionF(File file) { assert !bIsApplet; FileAbstraction res = new FileAbstraction(); res.localfile = file; res.bIsDirType = false; // unknown return res; } ///////////////////////////////////////////// static FileAbstraction MakeCurrentUserDirectory() { // this is used to start the file dialog off. To get it to land in the current // directory, rather than the directory above with the current directory selected, // it looks like we'd have to find a file/directory in this directory and select it. // this seems to be the limitations of JFileChooser.setSelectedFile File Linitialuserdir = new File("").getAbsoluteFile(); FileAbstraction fa = FileAbstraction.MakeDirectoryFileAbstractionF(Linitialuserdir); FileAbstraction fac = FileAbstraction.MakeCanonical(fa); return fac; } ///////////////////////////////////////////// static FileAbstraction MakeDirectoryFileAbstraction(String dname) { assert !bIsApplet; FileAbstraction res = new FileAbstraction(); res.localfile = new File(dname); res.bIsDirType = true; return res; } ///////////////////////////////////////////// static FileAbstraction MakeDirectoryFileAbstractionF(File dfile) { assert !bIsApplet; FileAbstraction res = new FileAbstraction(); res.localfile = dfile; res.bIsDirType = true; return res; } static FileAbstraction MakeDirectoryAndFileAbstraction(FileAbstraction dfile, String fname) { assert !bIsApplet; FileAbstraction res = new FileAbstraction(); res.localfile = (dfile != null ? new File(dfile.localfile, fname) : new File(fname)); res.bIsDirType = false; return res; } // case insensitive (often applies to survex files made under windows) static FileAbstraction MakeDirectoryAndFileAbstractionCI(FileAbstraction dfile, String fname) { assert !bIsApplet; FileAbstraction res = new FileAbstraction(); res.localfile = (dfile != null ? new File(dfile.localfile, fname) : new File(fname)); res.bIsDirType = false; // will be true for last call of function if (!res.localfile.exists() && (dfile.localfile != null) && dfile.localfile.isDirectory()) { for (File f : dfile.localfile.listFiles()) { if (fname.equalsIgnoreCase(f.getName())) { res.localfile = new File(dfile.localfile, f.getName()); System.out.println("MakeDirectoryAndFileAbstractionCI matches-- " + fname + " " + f.getName()); } } } return res; } ///////////////////////////////////////////// static FileAbstraction MakeCanonical(FileAbstraction fa) { if (fa.localurl != null) return fa; assert !bIsApplet; FileAbstraction res = new FileAbstraction(); try { res.localfile = new File(fa.localfile.getCanonicalPath()); } catch (IOException e) {;}; res.bIsDirType = fa.bIsDirType; return res; } ///////////////////////////////////////////// // replaces GetBufferedReader which doesn't allow for closing the original stream! InputStream GetInputStream() throws IOException { if (localurl != null) return localurl.openStream(); assert !bIsApplet; return new FileInputStream(localfile); } ///////////////////////////////////////////// String ReadFileHead() { // the XML file types require loading the header to determin what's in them // look for the xml tag that follows String sfilehead = ""; try { InputStream inputstream = GetInputStream(); InputStreamReader inputstreamreader = new InputStreamReader(inputstream); int lfilehead = inputstreamreader.read(filehead, 0, filehead.length); inputstream.close(); if (lfilehead == -1) { TN.emitWarning("**** left file unknown on " + getName()); return ""; } sfilehead = new String(filehead, 0, lfilehead); } catch (IOException e) { TN.emitWarning(e.toString()); } return sfilehead; } ///////////////////////////////////////////// // read characters until count nLB of < brackets String ReadFileHeadLB(int nLB) { // the XML file types require loading the header to determin what's in them // look for the xml tag that follows StringBuffer sb = new StringBuffer(); try { InputStream inputstream = GetInputStream(); InputStreamReader inputstreamreader = new InputStreamReader(inputstream); for (int i = 0; ((nLB == -1) || (i < 1024)); i++) { int ch = inputstreamreader.read(); if (ch == -1) break; sb.append((char)ch); if ((nLB != -1) && (ch == '<')) { nLB--; if (nLB == 0) break; } } inputstream.close(); } catch (FileNotFoundException e) { TN.emitWarning(e.toString()); return null; } catch (IOException e) { TN.emitWarning(e.toString()); } return sb.toString(); } ///////////////////////////////////////////// // we could use this opportunity to detect the version, project and user for this file // also should record dates (changed in upload) // looks for the object type listed after the tunnelxml static char[] filehead = new char[1024]; int GetFileType() { String fname = getName(); if (fname.startsWith(".#")) return FileAbstraction.FA_FILE_IGNORE; if (fname.endsWith("~")) return FileAbstraction.FA_FILE_IGNORE; String suff = TN.getSuffix(fname); // work some out from just the suffix if (suff.equals(TN.SUFF_SVX)) return FA_FILE_SVX; if (suff.equals(TN.SUFF_POS)) return FA_FILE_POS; if (suff.equals(TN.SUFF_3D)) return FA_FILE_3D; if (suff.equalsIgnoreCase(TN.SUFF_PNG) || suff.equalsIgnoreCase(TN.SUFF_GIF) || suff.equalsIgnoreCase(TN.SUFF_JPG)) return FA_FILE_IMAGE; if (suff.equalsIgnoreCase(TN.SUFF_TXT)) { String sfilehead = ReadFileHead(); if (PocketTopoLoader.IsPocketTopo(sfilehead)) return FA_FILE_POCKET_TOPO; return FA_FILE_IGNORE; } if (suff.equals(TN.SUFF_TOP)) return FA_FILE_POCKET_BINTOP; if (suff.equals(TN.SUFF_HTML)) return FA_FILE_HTML; if (suff.equals(TN.SUFF_PDF)) return FA_FILE_PDF; if (suff.equals(TN.SUFF_SVG)) return FA_FILE_SVG; // remaining non-xml types if (!suff.equalsIgnoreCase(TN.SUFF_XML)) { for (int i = 0; i < TN.SUFF_IGNORE.length; i++) if (suff.equalsIgnoreCase(TN.SUFF_IGNORE[i])) return FA_FILE_IGNORE; TN.emitMessage("Unknown file type " + getName()); return FA_FILE_UNKNOWN; } // the XML file types require loading the header to determin what's in them // look for the xml tag that follows String sfilehead = ReadFileHeadLB(4); //TN.emitMessage("READ " + sfilehead.length() + " chars of " + getName()); if (sfilehead == null) { TN.emitWarning("**** file not found " + getName()); return FA_FILE_UNKNOWN; } String strtunnxml = " int bracklo = sfilehead.indexOf('<', itunnxml + strtunnxml.length()); int brackhic = sfilehead.indexOf('>', bracklo + 1); int brackhis = sfilehead.indexOf(' ', bracklo + 1); int brackhi = (brackhis != -1 ? Math.min(brackhic, brackhis) : brackhic); if ((bracklo == -1) || (brackhi == -1)) { TN.emitWarning("**** missing bracket on " + getName() + " " + bracklo + " " + brackhic + " " + brackhis + " " + brackhi); System.out.println("FILEHEAD: " + sfilehead); return FA_FILE_UNKNOWN; } String sres = sfilehead.substring(bracklo + 1, brackhi); if (sres.equals("sketch")) return FA_FILE_XML_SKETCH; if (sres.equals("exports")) return FA_FILE_XML_EXPORTS; if (sres.equals("measurements")) return FA_FILE_XML_MEASUREMENTS; if (sres.equals("fontcolours")) return FA_FILE_XML_FONTCOLOURS; TN.emitWarning("**** what's sres " + sres + " " + getName()); return FA_FILE_UNKNOWN; } ///////////////////////////////////////////// // we could construct a miniclass or structure of vectors with // indexes from the xfiletype values, that recurses and gives us the entire tree of // FileAbstractions, which may be URLs or Files. // need to build up the tree structure separately, and then import into all the tunnels. // so that the tree/file information can be transmitted at once from the server. // and then later the different FileAbstractions can pull the data from URLs rather than // the File. // Or at the very least, make listFilesDir(dod) the secret of what can be got from the // server, and this forms the basis for pulling anything in. ///////////////////////////////////////////// List listFilesDir() throws IOException { TN.emitWarning("using alternative to listFilesDir"); return GetDirContents(); /* List res = new ArrayList(); if (localurl != null) { URL urllistdir = localurl; //System.out.println("eee " + urllistdir); //DumpURL(urllistdir); BufferedReader br = new BufferedReader(new InputStreamReader(urllistdir.openStream())); List sres = new ArrayList(); String lfile; while ((lfile = br.readLine()) != null) sres.add(lfile); Collections.sort(sres); for (String llfile : sres) { FileAbstraction faf = new FileAbstraction(); faf.localurl = new URL(urllistdir, llfile); //System.out.println(faf.localurl + " = " + urllistdir + " " + llfile); faf.xfiletype = faf.GetFileType(); // part of the constructor? //System.out.println(" Nnnnn " + faf.getName() + " " + faf.xfiletype); res.add(faf); } br.close(); return res; } assert !bIsApplet; assert localfile.isDirectory(); List sfileslist = Arrays.asList(localfile.listFiles()); Collections.sort(sfileslist); for (File sfile : sfileslist) { File tfile = sfile.getCanonicalFile(); if (tfile.isFile()) { FileAbstraction faf = FileAbstraction.MakeOpenableFileAbstractionF(tfile); faf.xfiletype = faf.GetFileType(); // part of the constructor? res.add(faf); } } return res; */ } // used only in the TunnelXMLparse when loading the name for the survex executable static boolean isDirectory(String ldir) { assert !bIsApplet; return new File(ldir).isDirectory(); } ///////////////////////////////////////////// List GetDirContents() throws IOException { List res = new ArrayList(); if ((localurl != null) && localurl.getProtocol().equals("jar")) { String slocalurl = localurl.toString(); TN.emitMessage("Reading dircontents from: "+slocalurl); String rnameheader = slocalurl.substring(slocalurl.lastIndexOf("!")+2, slocalurl.length()-11); BufferedReader br = new BufferedReader(new InputStreamReader(localurl.openStream())); String lfile; ClassLoader cl = MainBox.class.getClassLoader(); while ((lfile = br.readLine()) != null) { if (lfile.equals("listdir.txt")) continue; String rname = rnameheader + lfile; FileAbstraction faf = new FileAbstraction(); faf.localurl = cl.getResource(rname); if (faf.localurl == null) { TN.emitWarning("File "+lfile+" not in jar file"); continue; } faf.xfiletype = faf.GetFileType(); // part of the constructor? if ((faf.xfiletype == FA_FILE_XML_SKETCH) || (faf.xfiletype == FA_FILE_XML_FONTCOLOURS) || (faf.xfiletype == FA_FILE_IMAGE) || (faf.xfiletype == FA_FILE_SVX) || (faf.xfiletype == FA_FILE_POCKET_BINTOP)) res.add(faf); } } else if ((localurl == null) || localurl.getProtocol().equals("file")) { assert (((localurl != null) && localurl.getProtocol().equals("file")) || (localfile != null)); File llocalfile = (localurl != null ? new File(localurl.getPath()) : localfile); // handle localurl which is a file case assert llocalfile.isDirectory(); List sfileslist = Arrays.asList(llocalfile.listFiles()); for (File sfile : sfileslist) { File tfile = sfile.getCanonicalFile(); if (tfile.isFile()) { FileAbstraction faf = FileAbstraction.MakeOpenableFileAbstractionF(tfile); faf.xfiletype = faf.GetFileType(); // part of the constructor? if ((faf.xfiletype == FA_FILE_XML_SKETCH) || (faf.xfiletype == FA_FILE_XML_FONTCOLOURS) || (faf.xfiletype == FA_FILE_IMAGE) || (faf.xfiletype == FA_FILE_SVX) || (faf.xfiletype == FA_FILE_POCKET_BINTOP)) res.add(faf); } else if (tfile.isDirectory()) { FileAbstraction faf = FileAbstraction.MakeOpenableFileAbstractionF(tfile); faf.bIsDirType = true; faf.xfiletype = FA_DIRECTORY; if (!tfile.getName().startsWith(".") && !tfile.getName().equals("CVS")) // skip .svn and CSV files res.add(faf); } } } // url types (a very crude parsing of the default directory listing page provided by apache // eg http://seagrass.goatchurch.org.uk/~expo/mmmmc-thinned-hg/tunneldata/ else if (localurl.getPath().indexOf("~") != -1) { byte[] buffer = new byte[1024]; BufferedReader br = new BufferedReader(new InputStreamReader(localurl.openStream())); List sres = new ArrayList(); String lfile; String line; boolean bindexoftitle = false; boolean bparentdir = false; while ((line = br.readLine()) != null) { //TN.emitMessage(line); if (line.indexOf("Index of") != -1) bindexoftitle = true; else if (line.indexOf(">Parent Directory</a></td>") != -1) bparentdir = true; else if (bindexoftitle && bparentdir) { int il = line.indexOf("<a href=\""); if (il != -1) { int ie = line.indexOf('"', il+9); if (ie != -1) { FileAbstraction faf = new FileAbstraction(); faf.localurl = new URL(localurl, line.substring(il+9, ie)); if (line.charAt(ie-1) == '/') { faf.bIsDirType = true; faf.xfiletype = FA_DIRECTORY; res.add(faf); } else { faf.xfiletype = faf.GetFileType(); if ((faf.xfiletype == FA_FILE_XML_SKETCH) || (faf.xfiletype == FA_FILE_XML_FONTCOLOURS) || (faf.xfiletype == FA_FILE_IMAGE) || (faf.xfiletype == FA_FILE_SVX)) res.add(faf); } } } } } } else { Pattern fildir = Pattern.compile("<a class=\"(.*?)\" href=\"(.*?)\">"); String urlpath = localurl.getPath(); boolean bjgtfile = (urlpath.indexOf("/jgtfile/") != -1); //<li class="file"><a href="/troggle/jgtfile/tunneldata2007/204area.3d">tunneldata2007/204area.3d</a> (148607 bytes)</li> // http://troggle.cavingexpedition.com/troggle/jgtfile/tunneldata2007 URL urllistdir = localurl; //System.out.println("eee " + urllistdir); //DumpURL(urllistdir); TN.emitMessage("Reading... " + urlpath); BufferedReader br = new BufferedReader(new InputStreamReader(localurl.openStream())); List<String> sres = new ArrayList<String>(); String lfile; while ((lfile = br.readLine()) != null) { TN.emitMessage("::: "+lfile); Matcher mdir = fildir.matcher(lfile); if (mdir.find()) { System.out.println("jsdfsdf " + mdir.group(1) + " " + mdir.group(2)); if (mdir.group(1).equals("subdir")) { FileAbstraction faf = new FileAbstraction(); faf.localurl = new URL(localurl, mdir.group(2)); faf.bIsDirType = true; faf.xfiletype = FA_DIRECTORY; res.add(faf); } if (mdir.group(1).equals("filesketch")) { FileAbstraction faf = new FileAbstraction(); faf.localurl = new URL(localurl, mdir.group(2)); faf.xfiletype = FA_FILE_XML_SKETCH; res.add(faf); } if (mdir.group(1).equals("filesvx")) { FileAbstraction faf = new FileAbstraction(); faf.localurl = new URL(localurl, mdir.group(2)); faf.xfiletype = FA_FILE_SVX; res.add(faf); } if (mdir.group(1).equals("filefontcolours")) { FileAbstraction faf = new FileAbstraction(); faf.localurl = new URL(localurl, mdir.group(2)); faf.xfiletype = FA_FILE_XML_FONTCOLOURS; res.add(faf); } if (mdir.group(1).equals("fileimage")) { FileAbstraction faf = new FileAbstraction(); faf.localurl = new URL(localurl, mdir.group(2)); faf.xfiletype = FA_FILE_IMAGE; res.add(faf); } } } } Collections.sort(res, new Comparator<FileAbstraction>() { public int compare(FileAbstraction fa1, FileAbstraction fa2) { if ((fa1.xfiletype == FA_DIRECTORY) != (fa2.xfiletype == FA_DIRECTORY)) return (fa1.xfiletype == FA_DIRECTORY ? -1 : 1); return (fa1.getName().compareTo(fa2.getName())); }}); return res; } ///////////////////////////////////////////// ///////////////////////////////////////////// void FindFilesOfDirectory(List<OneSketch> tsketches, List<FileAbstraction> tfontcolours) throws IOException { List<FileAbstraction> fod = listFilesDir(); // here we begin to open XML readers and such like, filling in the different slots. boolean bsomethinghere = false; for (FileAbstraction tfile : fod) { int iftype = tfile.xfiletype; // fill in the file positions according to what was in this file. if (iftype == FileAbstraction.FA_FILE_XML_SKETCH) { tsketches.add(new OneSketch(tfile)); bsomethinghere = true; } else if (iftype == FileAbstraction.FA_FILE_XML_FONTCOLOURS) tfontcolours.add(tfile); } } ///////////////////////////////////////////// static void DumpURL(URL url) { try { System.out.println("Printing contents of: " + url); BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream())); String sline; while ((sline = br.readLine()) != null) System.out.println("JJJ: " + sline); br.close(); System.out.println("ENDS"); } catch (IOException ioe) { System.out.println("Exception:" + ioe); } } ///////////////////////////////////////////// static BufferedImage cachedframedimage = null; // some very limited caching for use by UI when reselecting the windows static String cachedframedimageabspath = ""; BufferedImage GetImage(boolean bFramed) { if ((cachedframedimage != null) && getAbsolutePath().equals(cachedframedimageabspath)) { //TN.emitMessage("Reusing cached image: " + getAbsolutePath()); return cachedframedimage; } BufferedImage res = null; try { TN.emitMessage("Loading image: " + getAbsolutePath()); if (localfile != null) res = ImageIO.read(localfile); else if (localurl != null) res = ImageIO.read(localurl); if (res == null) { String[] imnames = ImageIO.getReaderFormatNames(); System.out.println("Image reader format names: "); for (int i = 0; i < imnames.length; i++) System.out.println(imnames[i]); } } catch (IOException e) { TN.emitWarning("getimageIO " + e.toString()); }; if (bFramed) { cachedframedimage = res; cachedframedimageabspath = getAbsolutePath(); } return res; } ///////////////////////////////////////////// FileAbstraction SaveAsDialog(int ftype, JFrame frame, boolean bauto) // sketch/print=false/true { // this == sketchgraphicspanel.sketchdisplay, but for the fact we're in an anonymous event listner //int ftype = (bsketchprint ? SvxFileDialog.FT_XMLSKETCH : SvxFileDialog.FT_BITMAP); SvxFileDialog sfd = SvxFileDialog.showSaveDialog(this, frame, ftype, bauto); if (sfd == null) return null; FileAbstraction res = sfd.getSelectedFileA(ftype, true); if ((res.localurl == null) && !bauto) { if (ftype == SvxFileDialog.FT_XMLSKETCH) TN.currentDirectory = res; else TN.currprintdir = (res.isDirectory() ? res : res.getParentFile()); } return res; } ///////////////////////////////////////////// ///////////////////////////////////////////// ///////////////////////////////////////////// ///////////////////////////////////////////// ///////////////////////////////////////////// static boolean SurvexExists() { if (bIsApplet) return false; return new File(TN.survexexecutabledir).isDirectory(); } ///////////////////////////////////////////// ///////////////////////////////////////////// // this will need to be runable through the web static boolean RunSurvex(SurvexLoaderNew sln, String drawlab, Vec3 appsketchLocOffset, boolean bpreview) { File lposfile = null; if (!tmpdir.isDirectory()) { TN.emitWarning("Must create tunnelx/tmp directory to use this feature"); return false; } String tmpfilename = "tunnelx_tmp_all"; File lsvxfile = new File(tmpdir, TN.setSuffix(tmpfilename, TN.SUFF_SVX)); try { LineOutputStream los = new LineOutputStream(MakeWritableFileAbstractionF(lsvxfile)); LineInputStream lis = new LineInputStream(drawlab, null); int nsplaysdiscarded = 0; while (lis.FetchNextLine()) { if (lis.w[1].equals("-")) { if (nsplaysdiscarded == 0) TN.emitMessage("Discarding suspected splay line in svx file: "+lis.GetLine()); nsplaysdiscarded++; } else if (!bpreview && lis.w[1].startsWith("-") && lis.w[1].endsWith("-")) { if (nsplaysdiscarded == 0) TN.emitMessage("Discarding suspected -splay- line in svx file: "+lis.GetLine()); nsplaysdiscarded++; } else los.WriteLine(lis.GetLine()); } if (nsplaysdiscarded >= 2) TN.emitMessage("and further "+nsplaysdiscarded+" splays"); los.close(); } catch (IOException e) { TN.emitWarning(e.toString()); } File l3dfile = new File(tmpdir, TN.setSuffix(tmpfilename, TN.SUFF_3D)); if (l3dfile.isFile()) l3dfile.delete(); lposfile = new File(tmpdir, TN.setSuffix(tmpfilename, TN.SUFF_POS)); if (lposfile.isFile()) lposfile.delete(); if (sln == null) // preview aven lposfile = null; if (!RunCavern(tmpdir, lsvxfile, l3dfile, lposfile)) { TN.emitWarning("Failed to generate the 3D file"); return false; } // preview aven if (sln == null) { RunAven(tmpdir, l3dfile); return true; } try { FileAbstraction fapos = MakeWritableFileAbstractionF(lposfile); LineInputStream lis = new LineInputStream(fapos.GetInputStream(), fapos, null, null); boolean bres = sln.LoadPosFile(lis, appsketchLocOffset); lis.close(); lis.inputstream.close(); if (!bres) return false; } catch (IOException e) { TN.emitWarning(e.toString()); } return true; } ///////////////////////////////////////////// static boolean OperateProcess(ProcessBuilder pb, String pname) { try { pb.redirectErrorStream(true); Process p = pb.start(); BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())); String line; while ((line = br.readLine()) != null) TN.emitMessage(" " + pname + ":: " + line); int ires = p.waitFor(); if (ires == 0) return true; } catch (IOException ie) { TN.emitWarning("@@ caught exception"); TN.emitWarning(ie.toString()); ie.printStackTrace(); } catch (InterruptedException ie) { TN.emitWarning("@@ caught Interrupted exception"); TN.emitWarning(ie.toString()); ie.printStackTrace(); } return false; } ///////////////////////////////////////////// static boolean RunCavern(File ldirectory, File lsvxfile, File l3dfile, File lposfile) { List<String> cmds = new ArrayList<String>(); cmds.add(TN.survexexecutabledir + "cavern"); cmds.add("--no-auxiliary-files"); cmds.add("--quiet"); // or -qq for properly quiet cmds.add("-o"); cmds.add(l3dfile.getPath()); cmds.add(lsvxfile.getPath()); ProcessBuilder pb = new ProcessBuilder(cmds); pb.directory(ldirectory); if (!OperateProcess(pb, "cavern")) return false; if (!l3dfile.exists()) return false; if (lposfile == null) return true; cmds.clear(); cmds.add(TN.survexexecutabledir + "3dtopos"); cmds.add(l3dfile.getPath()); cmds.add(lposfile.getPath()); //System.out.println("SVX path: " + tunnelfilelist.activetunnel.svxfile.getPath()); ProcessBuilder pb3 = new ProcessBuilder(cmds); pb3.directory(ldirectory); if (!OperateProcess(pb3, "3dtopos")) return false; if (!lposfile.exists()) return false; return true; } ///////////////////////////////////////////// static boolean RunAven(File ldirectory, File l3dfile) { assert l3dfile != null; ProcessBuilder pb = new ProcessBuilder(TN.survexexecutabledir + "aven", l3dfile.getPath()); pb.directory(ldirectory); OperateProcess(pb, "aven"); return true; } ///////////////////////////////////////////// ///////////////////////////////////////////// static List<String> imagefiledirectories = new ArrayList<String>(); static void AddImageFileDirectory(String newimagefiledirectory) { for (String limagefiledirectory : imagefiledirectories) { if (limagefiledirectory.equals(newimagefiledirectory)) { TN.emitMessage("Already have imagefiledirectory: " + limagefiledirectory); return; } } imagefiledirectories.add(newimagefiledirectory); } // this goes up the directories looking in them for the iname file // and for any subdirectories of these matching an element in imagefiledirectories static FileAbstraction GetImageFile(FileAbstraction idir, String iname) { TN.emitMessage("GetImageFile: "+iname); if (iname.startsWith("http:")) { FileAbstraction res = MakeOpenableFileAbstraction(iname); if (res.localurl != null) return res; } if (iname.startsWith("jarresource:")) { FileAbstraction res = MakeOpenableFileAbstraction(iname); if (res.localurl != null) return res; } if (idir == null) return null; // get the path from troggle if we can if (idir.localurl != null) { try { String sname = iname.replace("#", "%23"); sname = sname.replace("http://", ""); FileAbstraction rread = MakeOpenableFileAbstraction(idir.localurl.toString() + "/backgroundscan/" + sname); TN.emitMessage("---- " + rread.localurl.toString()); LineInputStream lis = new LineInputStream(rread.GetInputStream(), rread, null, null); lis.FetchNextLine(); if (lis.w[0].equals("imageforward=")) { FileAbstraction res = MakeOpenableFileAbstraction(lis.w[1]); lis.close(); lis.inputstream.close(); return res; } System.out.println("::" + lis.GetLine()); while (lis.FetchNextLine()) System.out.println("::" + lis.GetLine()); lis.inputstream.close(); } catch (IOException e) { TN.emitWarning("bbad url " + iname + " " + e.toString()); } } // non-troggle (same recursion as with files, only not so easy) if (idir.localurl != null) { String sname = iname.replace("#", "%23"); idir = idir.getParentFile(); while (idir != null) { for (int i = imagefiledirectories.size() - 1; i >= 0; i--) { FileAbstraction res = new FileAbstraction(); try { res.localurl = new URL(idir.localurl, imagefiledirectories.get(i) + sname); } catch (MalformedURLException e) { continue; } //TN.emitMessage("---- " + res.localurl.toString()); // implement isFile() for URLs try { InputStream is = res.GetInputStream(); is.read(); return res; } catch (IOException e) {;} } idir = idir.getParentFile(); } return null; } // recurse up the file structure while (idir != null) { // check if this image file is in the directory FileAbstraction res = FileAbstraction.MakeDirectoryAndFileAbstraction(idir, iname); if (res.isFile()) return res; // check if it is in one of the image file subdirectories for (int i = imagefiledirectories.size() - 1; i >= 0; i--) { FileAbstraction lidir = FileAbstraction.MakeDirectoryAndFileAbstraction(idir, imagefiledirectories.get(i)); if (lidir.isDirectory()) { res = FileAbstraction.MakeDirectoryAndFileAbstraction(lidir, iname); if (res.isFile()) return res; } } // recurse up the hierarchy if (idir.localfile == null) break; idir = idir.getParentFile(); } return null; } // we have to decode the file to find something that will satisfy the function above static String GetImageFileName(FileAbstraction idir, FileAbstraction ifile) throws IOException { if ((ifile.localurl != null) && ifile.localurl.toString().startsWith("jar:file:")) { String slocalurl = ifile.localurl.toString(); int ijarresource = slocalurl.lastIndexOf("!/"); if (ijarresource == -1) TN.emitError("Cannot decode: "+ slocalurl); String res = "jarresource:"+slocalurl.substring(ijarresource+2).replace("/", "!"); TN.emitMessage("HIHIHIH: "+ res); return res; } if (ifile.localurl != null) { if (idir.localurl == null) return ifile.localurl.toString(); TN.emitMessage(ifile.localurl.getHost() + " " + idir.localurl.getHost()); TN.emitMessage("FFF: " + ifile.localurl.getFile()); if (ifile.localurl.getHost().equals(idir.localurl.getHost())) return ifile.localurl.getFile(); // just the string part after the host return ifile.localurl.toString(); } // we need to find a route which takes us here String sfiledir = ifile.getParentFile().getCanonicalPath(); FileAbstraction ridir = FileAbstraction.MakeCanonical(idir); while (ridir != null) { String sdir = ridir.getCanonicalPath(); if (sfiledir.startsWith(sdir)) { // look through the image file directories to find one that takes us down towards the file FileAbstraction lridir = null; for (int i = imagefiledirectories.size() - 1; i >= 0; i--) // in reverse so last ones have highest priority { FileAbstraction llridir = FileAbstraction.MakeDirectoryAndFileAbstraction(ridir, imagefiledirectories.get(i)); if (llridir.isDirectory()) { String lsdir = llridir.getCanonicalPath(); if (sfiledir.startsWith(lsdir)) { lridir = llridir; break; } } } // found an image directory which is part of the stem if (lridir != null) { ridir = lridir; break; } } ridir = ridir.getParentFile(); // keep going up. } if (ridir == null) { TN.emitWarning("No common stem found"); TN.emitWarning(idir.getCanonicalPath()); TN.emitWarning(ifile.getCanonicalPath()); return null; } // find the root of which sdir is the stem StringBuffer sbres = new StringBuffer(); FileAbstraction lifile = ifile; while (lifile != null) { if (sbres.length() != 0) sbres.insert(0, "/"); sbres.insert(0, lifile.getName()); lifile = lifile.getParentFile(); if ((lifile == null) || lifile.equals(ridir)) break; } String sres = sbres.toString(); TN.emitMessage("Making stem file: " + sres); FileAbstraction tifile = GetImageFile(idir, sres); if ((tifile != null) && ifile.equals(tifile)) return sres; TN.emitWarning("Stem file failure: " + idir.toString()); TN.emitWarning(ifile.toString()); if (tifile != null) TN.emitWarning(tifile.toString()); return null; } ///////////////////////////////////////////// // goes through files that exist and those that are intended to be saved static FileAbstraction GetUniqueSketchFileName(FileAbstraction tundirectory, List<OneSketch> tsketches, String lname) { if (tundirectory.localurl != null) { System.out.println(tundirectory.bIsDirType + " " + tundirectory.xfiletype + " " + tundirectory.getPath()); // should be save to disk type return tundirectory; // want to ask the server to give a new one } if (!tundirectory.bIsDirType) tundirectory = tundirectory.getParentFile(); int sknum = -1; FileAbstraction res; while (true) { res = FileAbstraction.MakeDirectoryAndFileAbstraction(tundirectory, lname + (sknum == -1 ? "" : String.valueOf(sknum)) + ".xml"); res.xfiletype = FileAbstraction.FA_FILE_XML_SKETCH; sknum = (sknum == -1 ? tsketches.size() + 1 : 1); boolean bexists = res.localfile.exists(); for (OneSketch tsketch : tsketches) { if (res.equals(tsketch.sketchfile)) bexists = true; } if (!bexists) break; } return res; } static FileAbstraction calcIncludeFile(FileAbstraction orgfile, String fname, boolean bPosType) { if ((orgfile == null) || ((fname.length() > 3) && (fname.charAt(1) == ':'))) return FileAbstraction.MakeOpenableFileAbstraction(fname); FileAbstraction cdirectory = orgfile.getParentFile(); String fnamesuff = TN.getSuffix(fname); char lsep; // deal with the up directory situation. if (fname.startsWith("..\\") || fname.startsWith("../")) { // TN.emitMessage("**" + cdirectory + " + " + fname); lsep = '\\'; while (fname.startsWith("..\\") || fname.startsWith("../")) { // this is all a bit junk and should be redone using basic join libraries fname = fname.substring(3); int ndr = cdirectory.getAbsolutePath().lastIndexOf(lsep); if (ndr == -1) ndr = cdirectory.getAbsolutePath().lastIndexOf('/'); if (ndr != -1) cdirectory = cdirectory.getParentFile(); else { TN.emitWarning("Failed to go up directory:" + lsep + ":" + cdirectory.getName().substring(cdirectory.getName().length() - 4)); char atatat = cdirectory.getName().charAt(cdirectory.getName().length() - 4); TN.emitWarning("hh " + atatat + " " + (lsep == atatat)); } } TN.emitMessage(" = " + cdirectory + " + " + fname); } else { // find local file separator if (fnamesuff.equalsIgnoreCase(TN.SUFF_SVX) || fnamesuff.equalsIgnoreCase(TN.SUFF_SRV)) lsep = '\\'; else if (fname.indexOf('.') != -1) lsep = '.'; else if (fname.indexOf('/') != -1) lsep = '/'; else if (fname.indexOf('\\') != -1) lsep = '\\'; else lsep = '\\'; //TN.emitMessage("fname of " + fname + " suff " + fnamesuff + " sep " + lsep); } // replace delimeter characters with the separator character. int idot; while ((idot = fname.indexOf(lsep)) != -1) { cdirectory = FileAbstraction.MakeDirectoryAndFileAbstractionCI(cdirectory, fname.substring(0, idot)); fname = fname.substring(idot + 1); } if (bPosType) fname = fname + TN.SUFF_POS; else if (lsep == '\\') fname = TN.setSuffix(fname, TN.getSuffix(!fnamesuff.equalsIgnoreCase(TN.SUFF_SRV) ? orgfile.getName() : fname)); else fname = fname + TN.getSuffix(orgfile.getName()); //TN.emitMessage("include file " + cdirectory + " \\ " + fname); return(FileAbstraction.MakeDirectoryAndFileAbstractionCI(cdirectory, fname)); } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/src/SketchZTiltPanel.java�����������������������������������������������������0000644�0000000�0000000�00000054441�12261213471�016120� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2012 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import javax.swing.JPanel; import javax.swing.JButton; import javax.swing.JRadioButton; import javax.swing.ButtonGroup; import javax.swing.JTextField; import javax.swing.JTextArea; import javax.swing.JLabel; import javax.swing.JCheckBox; import java.awt.event.MouseListener; import java.awt.event.MouseEvent; import java.awt.event.MouseAdapter; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JList; import javax.swing.ListModel; import javax.swing.DefaultListModel; import javax.swing.ListSelectionModel; import javax.swing.event.ListSelectionListener; import javax.swing.event.ListSelectionEvent; import javax.swing.JLabel; import javax.swing.ListCellRenderer; import java.awt.Component; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.CardLayout; import java.awt.Insets; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.awt.geom.Point2D; import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.AffineTransform; import java.awt.Color; import java.util.Set; import java.util.List; import java.util.ArrayList; ///////////////////////////////////////////// class SketchZTiltPanel extends JPanel { SketchDisplay sketchdisplay; JButton buttselecttozselection = new JButton("Select to Z Selection"); JCheckBox cbaShowTilt; JCheckBox cbaThinZheightsel; JCheckBox cbaAnimateTour; JButton buttanimatestep; JTextField tfzlothinnedvisible = new JTextField(); JTextField tfzhithinnedvisible = new JTextField(); JTextField tfzstep = new JTextField("10.0"); // z range thinning boolean bzthinnedvisible = false; // causes reselecting of subset of paths in RenderBackground double zlothinnedvisible = -360.0; double zhithinnedvisible = 20.0; // animations along a sequence of centrelines List<OnePathNode> opnpathanimation = new ArrayList<OnePathNode>(); int opnpathanimationPos = 0; // animations that change the sketch frame List< List<OnePath> > skopchains = new ArrayList< List<OnePath> >(); float nskopchainpos; // integral part defines which two positions we are between ///////////////////////////////////////////// SketchZTiltPanel(SketchDisplay lsketchdisplay) { sketchdisplay = lsketchdisplay; cbaShowTilt = new JCheckBox("Show Tilted in z", false); cbaShowTilt.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { if (sketchdisplay.miShowTilt.isSelected() != cbaShowTilt.isSelected()) sketchdisplay.miShowTilt.doClick(); } } ); cbaThinZheightsel = new JCheckBox("Thin Z Selection", false); cbaThinZheightsel.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { if (sketchdisplay.miThinZheightsel.isSelected() != cbaThinZheightsel.isSelected()) sketchdisplay.miThinZheightsel.doClick(); } } ); tfzhithinnedvisible.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { zhithinnedvisible = Float.parseFloat(tfzhithinnedvisible.getText()) - sketchdisplay.sketchgraphicspanel.tsketch.sketchLocOffset.z; } catch(NumberFormatException nfe) {;} SetUpdatezthinned(); }}); tfzlothinnedvisible.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { zlothinnedvisible = Float.parseFloat(tfzlothinnedvisible.getText()) - sketchdisplay.sketchgraphicspanel.tsketch.sketchLocOffset.z; } catch(NumberFormatException nfe) {;} SetUpdatezthinned(); }}); buttselecttozselection.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { SelectiontoZheightSelected(); SetUpdatezthinned(); }}); tfzlothinnedvisible.setText(String.valueOf(zlothinnedvisible + sketchdisplay.sketchgraphicspanel.tsketch.sketchLocOffset.z)); tfzhithinnedvisible.setText(String.valueOf(zhithinnedvisible + sketchdisplay.sketchgraphicspanel.tsketch.sketchLocOffset.z)); cbaAnimateTour = new JCheckBox("Animate Tour", false); cbaAnimateTour.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { if (cbaAnimateTour.isSelected()) SetupAnimateTour(); } } ); buttanimatestep = new JButton("Animate Step"); buttanimatestep.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { AnimateStep(); }}); JPanel panuppersec = new JPanel(new GridLayout(0, 2)); panuppersec.add(cbaThinZheightsel); panuppersec.add(cbaShowTilt); panuppersec.add(new JButton(sketchdisplay.acvThinZheightselWiden)); panuppersec.add(new JButton(sketchdisplay.acvTiltOver)); panuppersec.add(new JButton(sketchdisplay.acvThinZheightselNarrow)); panuppersec.add(new JButton(sketchdisplay.acvTiltBack)); panuppersec.add(buttselecttozselection); panuppersec.add(new JButton(sketchdisplay.acvUpright)); panuppersec.add(new JLabel()); panuppersec.add(new JButton(sketchdisplay.acvMovePlaneDown)); panuppersec.add(new JLabel()); panuppersec.add(new JButton(sketchdisplay.acvMovePlaneUp)); panuppersec.add(new JLabel("zhi-thinned:")); panuppersec.add(tfzhithinnedvisible); panuppersec.add(new JLabel("zlo-thinned:")); panuppersec.add(tfzlothinnedvisible); panuppersec.add(new JLabel("zstep:")); panuppersec.add(tfzstep); panuppersec.add(cbaAnimateTour); panuppersec.add(buttanimatestep); setLayout(new BorderLayout()); add(panuppersec, BorderLayout.CENTER); } ///////////////////////////////////////////// void SetupAnimateTour() { // animating on a sequence of centreline nodes OnePath op = sketchdisplay.sketchgraphicspanel.currgenpath; if ((op != null) && (op.plabedl != null) && !op.plabedl.drawlab.equals("")) { LineInputStream lis = new LineInputStream(op.plabedl.drawlab, null); opnpathanimation.clear(); opnpathanimationPos = 0; while (lis.FetchNextLine()) { TN.emitMessage("anim on "+lis.w[0]); OnePathNode aopn = null; for (OnePathNode opn : sketchdisplay.sketchgraphicspanel.tsketch.vnodes) if ((opn.pnstationlabel != null) && (opn.pnstationlabel.endsWith(lis.w[0])) && ((aopn == null) || (aopn.pnstationlabel.length() <= opn.pnstationlabel.length()))) aopn = opn; TN.emitMessage("kk" + aopn); opnpathanimation.add(aopn); } if (opnpathanimation.size() == 0) cbaAnimateTour.setSelected(false); } // animating on a sequence of sketchframes skopchains.clear(); for (OneSArea osa : sketchdisplay.sketchgraphicspanel.tsketch.vsareas) { if ((osa.opsketchframedefs == null) || (osa.opsketchframedefs.size() == 0)) continue; for (OnePath skop : osa.opsketchframedefs) { List<OnePath> skopchain = new ArrayList<OnePath>(); skopchain.add(skop); // the full connective line connective component code can be found in GetConnCompPath() // we assume that the connective lines are oriented forwards from the root // (multi coincident sketch frame definitions could be incoming at each node) RefPathO rpocopy = new RefPathO(); while (true) { RefPathO ropfore = new RefPathO(skopchain.get(skopchain.size() - 1), true); rpocopy.ccopy(ropfore); OnePath opnextfore = null; do { if ((rpocopy.op.linestyle != SketchLineStyle.SLS_CONNECTIVE) && (rpocopy.op.linestyle != SketchLineStyle.SLS_CENTRELINE)) break; if (!rpocopy.bFore && (rpocopy.op.linestyle == SketchLineStyle.SLS_CONNECTIVE)) { if (opnextfore != null) break; opnextfore = rpocopy.op; } } while (!rpocopy.AdvanceRoundToNode(ropfore)); if (!rpocopy.cequals(ropfore)) break; if (opnextfore == null) break; if (!opnextfore.IsSketchFrameConnective()/* && !op.plabedl.sketchframedef.sfsketch.equals("")*/) break; if (skopchain.contains(opnextfore)) break; TN.emitMessage("adding to skopchain "+opnextfore); skopchain.add(opnextfore); } if (skopchain.size() >= 3) { for (OnePath lskop : skopchain) lskop.plabedl.sketchframedef.SetSketchFrameFiller(sketchdisplay.mainbox, sketchdisplay.sketchgraphicspanel.tsketch.realposterpaperscale, sketchdisplay.sketchgraphicspanel.tsketch.sketchLocOffset, sketchdisplay.sketchgraphicspanel.tsketch.sketchfile); skopchains.add(skopchain); } else TN.emitMessage("skopchain size "+skopchain.size()+" discarded"); } } nskopchainpos = 1.0F; if (skopchains.size() == 0) cbaAnimateTour.setSelected(false); } ///////////////////////////////////////////// Point2D.Float scrpt = new Point2D.Float(); Point2D.Float realpt = new Point2D.Float(); double animdiststep = 10.1; void AnimateStep() { if (!opnpathanimation.isEmpty()) AnimateStepCentrelines(); else if (!skopchains.isEmpty()) AnimateFramePositions(); else cbaAnimateTour.setSelected(false); } ///////////////////////////////////////////// void AnimateFramePositions() { boolean bsetframe = false; int inskopchainpos = (int)nskopchainpos; float lam = nskopchainpos - inskopchainpos; Point2D.Float acenpt = new Point2D.Float(); Point2D.Float acenpt0 = new Point2D.Float(); Point2D.Float acenpt1 = new Point2D.Float(); Point2D.Float acenptlam = new Point2D.Float(); Point2D.Float acenptlamS = new Point2D.Float(); for (List<OnePath> skopchain : skopchains) { OnePath oproot = skopchain.get(0); assert oproot.IsSketchFrameConnective(); if (nskopchainpos > skopchain.size() - 1) continue; bsetframe = true; OnePath op0 = skopchain.get(inskopchainpos); assert op0.IsSketchFrameConnective(); if (lam == 0.0) { oproot.plabedl.sketchframedef.sfscaledown = op0.plabedl.sketchframedef.sfscaledown; oproot.plabedl.sketchframedef.sfrotatedeg = op0.plabedl.sketchframedef.sfrotatedeg; oproot.plabedl.sketchframedef.sfxtrans = op0.plabedl.sketchframedef.sfxtrans; oproot.plabedl.sketchframedef.sfytrans = op0.plabedl.sketchframedef.sfytrans; oproot.plabedl.sketchframedef.sfsketch = op0.plabedl.sketchframedef.sfsketch; } else { OnePath op1 = skopchain.get(inskopchainpos + 1); assert op1.IsSketchFrameConnective(); // we want the projection to the centre point of the area to be smooth acenpt.setLocation(oproot.kaleft.rboundsarea.getX() + oproot.kaleft.rboundsarea.getWidth()*0.5, oproot.kaleft.rboundsarea.getY() + oproot.kaleft.rboundsarea.getHeight()*0.5); try { op0.plabedl.sketchframedef.pframesketchtrans.inverseTransform(acenpt, acenpt0); op1.plabedl.sketchframedef.pframesketchtrans.inverseTransform(acenpt, acenpt1); } catch (NoninvertibleTransformException ex) {;} oproot.plabedl.sketchframedef.sfscaledown = op0.plabedl.sketchframedef.sfscaledown*(1.0F - lam) + op1.plabedl.sketchframedef.sfscaledown*lam; oproot.plabedl.sketchframedef.sfrotatedeg = op0.plabedl.sketchframedef.sfrotatedeg*(1.0F - lam) + op1.plabedl.sketchframedef.sfrotatedeg*lam; acenptlam.setLocation(acenpt0.getX()*(1.0 - lam) + acenpt1.getX()*lam, acenpt0.getY()*(1.0 - lam) + acenpt1.getY()*lam); AffineTransform lpframesketchtrans = new AffineTransform(); //pframesketchtrans.translate((-lsketchLocOffset.x + sfxtrans * lrealpaperscale) * TN.CENTRELINE_MAGNIFICATION, (+lsketchLocOffset.y + sfytrans * lrealpaperscale) * TN.CENTRELINE_MAGNIFICATION); lpframesketchtrans.scale(sketchdisplay.sketchgraphicspanel.tsketch.realposterpaperscale / oproot.plabedl.sketchframedef.sfscaledown, sketchdisplay.sketchgraphicspanel.tsketch.realposterpaperscale / oproot.plabedl.sketchframedef.sfscaledown); lpframesketchtrans.rotate(-Math.toRadians(oproot.plabedl.sketchframedef.sfrotatedeg)); lpframesketchtrans.translate(oproot.plabedl.sketchframedef.pframesketch.sketchLocOffset.x * TN.CENTRELINE_MAGNIFICATION, -oproot.plabedl.sketchframedef.pframesketch.sketchLocOffset.y * TN.CENTRELINE_MAGNIFICATION); lpframesketchtrans.transform(acenptlam, acenptlamS); //oproot.plabedl.sketchframedef.sfxtrans = op0.plabedl.sketchframedef.sfxtrans*(1.0F - lam) + op1.plabedl.sketchframedef.sfxtrans*lam; //oproot.plabedl.sketchframedef.sfytrans = op0.plabedl.sketchframedef.sfytrans*(1.0F - lam) + op1.plabedl.sketchframedef.sfytrans*lam; // solve: // (-lsketchLocOffset.x + sfxtrans * lrealpaperscale) * TN.CENTRELINE_MAGNIFICATION == acenptlamS.getX() - acenpt.getX() // (+lsketchLocOffset.y + sfytrans * lrealpaperscale) * TN.CENTRELINE_MAGNIFICATION == acenptlamS.getY() - acenpt.getY() // which comes from: pframesketchtrans.translate((-lsketchLocOffset.x + sfxtrans * lrealpaperscale) * TN.CENTRELINE_MAGNIFICATION, (+lsketchLocOffset.y + sfytrans * lrealpaperscale) * TN.CENTRELINE_MAGNIFICATION); oproot.plabedl.sketchframedef.sfxtrans = ((acenpt.getX() - acenptlamS.getX()) / TN.CENTRELINE_MAGNIFICATION + sketchdisplay.sketchgraphicspanel.tsketch.sketchLocOffset.x) / sketchdisplay.sketchgraphicspanel.tsketch.realposterpaperscale; oproot.plabedl.sketchframedef.sfytrans = ((acenpt.getY() - acenptlamS.getY()) / TN.CENTRELINE_MAGNIFICATION - sketchdisplay.sketchgraphicspanel.tsketch.sketchLocOffset.y) / sketchdisplay.sketchgraphicspanel.tsketch.realposterpaperscale; } oproot.plabedl.sketchframedef.SetSketchFrameFiller(sketchdisplay.mainbox, sketchdisplay.sketchgraphicspanel.tsketch.realposterpaperscale, sketchdisplay.sketchgraphicspanel.tsketch.sketchLocOffset, sketchdisplay.sketchgraphicspanel.tsketch.sketchfile); } if (bsetframe) { float lamstep = 0.1F; try { float llamstep = Float.parseFloat(tfzstep.getText()); lamstep = (llamstep > 1.0F ? 1.0F/llamstep : llamstep); } catch(NumberFormatException nfe) {;} float nlam = lam + lamstep; nskopchainpos = (nlam > 0.99 ? (float)(inskopchainpos + 1) : inskopchainpos + nlam); sketchdisplay.sketchgraphicspanel.bNextRenderDetailed = true; sketchdisplay.sketchgraphicspanel.RedoBackgroundView(); } else cbaAnimateTour.setSelected(false); } ///////////////////////////////////////////// void AnimateStepCentrelines() { Dimension csize = sketchdisplay.sketchgraphicspanel.csize; try { scrpt.setLocation(csize.width / 2, csize.height / 2); sketchdisplay.sketchgraphicspanel.currtrans.inverseTransform(scrpt, realpt); } catch (NoninvertibleTransformException ex) { realpt.setLocation(0, 0); } TN.emitMessage("opnpathanimationPos " + opnpathanimationPos + " " + opnpathanimation.size()); if (opnpathanimationPos >= opnpathanimation.size()) { cbaAnimateTour.setSelected(false); return; } Point2D.Float targetpt = opnpathanimation.get(opnpathanimationPos).pn; float targetz = opnpathanimation.get(opnpathanimationPos).zalt; double rx = realpt.getX(); double ry = realpt.getY(); double rz = (zlothinnedvisible + zhithinnedvisible) / 2; double vx = targetpt.getX() - rx; double vy = targetpt.getY() - ry; double vz = (sketchdisplay.miThinZheightsel.isSelected() ? targetz - rz : 0.0); double vlen = Math.sqrt(vx*vx + vy*vy + vz*vz); double lam = (animdiststep < vlen ? animdiststep / vlen : 1.0); if (lam == 1.0) opnpathanimationPos++; TN.emitMessage("lam " + lam); realpt.setLocation(rx + vx*lam, ry + vy*lam); sketchdisplay.sketchgraphicspanel.currtrans.transform(realpt, scrpt); //sketchdisplay.sketchgraphicspanel.Translate(-(scrpt.getX() - csize.width / 2) / csize.width, -(scrpt.getY() - csize.height / 2) / csize.height); sketchdisplay.sketchgraphicspanel.mdtrans.setToTranslation(-(scrpt.getX() - csize.width / 2), -(scrpt.getY() - csize.height / 2)); sketchdisplay.sketchgraphicspanel.orgtrans.setTransform(sketchdisplay.sketchgraphicspanel.currtrans); sketchdisplay.sketchgraphicspanel.currtrans.setTransform(sketchdisplay.sketchgraphicspanel.mdtrans); sketchdisplay.sketchgraphicspanel.currtrans.concatenate(sketchdisplay.sketchgraphicspanel.orgtrans); if (sketchdisplay.miThinZheightsel.isSelected()) { zlothinnedvisible = rz + vz*lam - animdiststep*10; zhithinnedvisible = rz + vz*lam + animdiststep*10; SetUpdatezthinned(); } else sketchdisplay.sketchgraphicspanel.RedoBackgroundView(); } ///////////////////////////////////////////// void SetUpdatezthinned() { if (zhithinnedvisible < zlothinnedvisible) zhithinnedvisible = zlothinnedvisible; tfzlothinnedvisible.setText(String.valueOf(zlothinnedvisible + sketchdisplay.sketchgraphicspanel.tsketch.sketchLocOffset.z)); tfzhithinnedvisible.setText(String.valueOf(zhithinnedvisible + sketchdisplay.sketchgraphicspanel.tsketch.sketchLocOffset.z)); sketchdisplay.sketchgraphicspanel.UpdateTilt(true); sketchdisplay.sketchgraphicspanel.RedoBackgroundView(); } ///////////////////////////////////////////// boolean SelectiontoZheightSelected() { sketchdisplay.sketchgraphicspanel.CollapseVActivePathComponent(); Set<OnePath> opselset = sketchdisplay.sketchgraphicspanel.MakeTotalSelList(); if (opselset.isEmpty()) return TN.emitWarning("No selection set for thinning by z so leaving the same"); boolean bfirst = true; for (OnePath op : opselset) { if (bfirst) { zlothinnedvisible = op.pnstart.zalt; zhithinnedvisible = op.pnstart.zalt; bfirst = false; } else { if (op.pnstart.zalt < zlothinnedvisible) zlothinnedvisible = op.pnstart.zalt; else if (op.pnstart.zalt > zhithinnedvisible) zhithinnedvisible = op.pnstart.zalt; } if (op.pnend.zalt < zlothinnedvisible) zlothinnedvisible = op.pnend.zalt; else if (op.pnend.zalt > zhithinnedvisible) zhithinnedvisible = op.pnend.zalt; } return true; } ///////////////////////////////////////////// void ApplyZheightSelected(boolean bthinbyheight) { // on selection if (bthinbyheight) { SelectiontoZheightSelected(); bzthinnedvisible = true; TN.emitMessage("Thinning on z " + zlothinnedvisible + " < " + zhithinnedvisible); } else // on deselection bzthinnedvisible = false; SetUpdatezthinned(); } ///////////////////////////////////////////// void WidenTiltPlane(int widencode) { double zwidgap = zhithinnedvisible - zlothinnedvisible; double zwidgapfac = (widencode == 1 ? zwidgap / 2 : -zwidgap / 4); zlothinnedvisible -= zwidgapfac; zhithinnedvisible += zwidgapfac; assert zlothinnedvisible <= zhithinnedvisible; TN.emitMessage("Rethinning on z " + zlothinnedvisible + " < " + zhithinnedvisible); SetUpdatezthinned(); } ///////////////////////////////////////////// void MoveTiltPlane(double stiltzchange) { double zstep = 50.0; try { zstep = Float.parseFloat(tfzstep.getText()); } catch(NumberFormatException nfe) {;} double tiltzchange = stiltzchange * zstep; zlothinnedvisible += tiltzchange; zhithinnedvisible += tiltzchange; SetUpdatezthinned(); } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/src/TunnelLoader.java���������������������������������������������������������0000644�0000000�0000000�00000005606�12261213471�015323� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.io.IOException; import java.util.List; // // // TunnelLoader // // ///////////////////////////////////////////// ///////////////////////////////////////////// class TunnelLoader { TunnelXMLparse txp; TunnelXML tunnXML; ///////////////////////////////////////////// ///////////////////////////////////////////// boolean LoadSketchFile(OneSketch tsketch, boolean bwritemessage) { assert !tsketch.bsketchfileloaded; tsketch.SetupSK(); FileAbstraction tfile = tsketch.sketchfile; String fnamess = TN.loseSuffix(tfile.getName()); txp.SetUp(fnamess, FileAbstraction.FA_FILE_XML_SKETCH); tsketch.bsketchfilechanged = false; if (txp.bSymbolType) { tsketch.bSymbolType = true; tsketch.sketchsymbolname = TN.loseSuffix(tfile.getName()); } txp.tunnelsketch = tsketch; boolean bloaded = tunnXML.ParseFile(txp, tfile); if (bwritemessage) TN.emitMessage("Loaded sketch (" + tsketch.sketchfile.getName() + "): project(" + tsketch.tunnelprojectloaded + "), user(" + tsketch.tunneluserloaded + "), date(" + tsketch.tunneldateloaded + "), tunnelversion(" + tsketch.tunnelversionloaded + ")"); return bloaded; } ///////////////////////////////////////////// void LoadFontcolour(FileAbstraction tfile) { try { System.out.println("Loading font colours:" + tfile.getName()); txp.SetUp(TN.loseSuffix(tfile.getName()), FileAbstraction.FA_FILE_XML_FONTCOLOURS); tunnXML.ParseFile(txp, tfile); } catch (NullPointerException e) { TN.emitWarning(e.toString()); e.printStackTrace(); }; } ///////////////////////////////////////////// ///////////////////////////////////////////// public TunnelLoader(boolean lbSymbolType, SketchLineStyle sketchlinestyle) { txp = new TunnelXMLparse(); txp.bSymbolType = lbSymbolType; txp.sketchlinestyle = sketchlinestyle; // for loading up the fontcolours tunnXML = new TunnelXML(); } }; ��������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/src/SelectedSubsetsStructure.java���������������������������������������������0000644�0000000�0000000�00000022511�11762432750�017753� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2007 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.util.List; import java.util.ArrayList; import java.util.Set; import java.util.HashSet; import java.util.Map; import java.awt.geom.Point2D; import java.awt.geom.Ellipse2D; import javax.swing.JTree; import javax.swing.tree.TreePath; import javax.swing.tree.DefaultMutableTreeNode; // this controls a set of subsets and the paths which are contained therein // also sets up the elevation when this selection fits the template. ///////////////////////////////////////////// class SelectedSubsetStructure { SketchDisplay sketchdisplay; Set<String> vsselectedsubsetsP = new HashSet<String>(); // actual selected Set<String> vsselectedsubsets = new HashSet<String>(); // transitive selected boolean binversubset = false; boolean btransitivesubset = false; //String selevsubset = null; // is the selected elevation subset // the structure of the elevation subset ElevSet elevset = new ElevSet(); //float vcenX; //SSymbScratchPath Tsscratchpath = new SSymbScratchPath(); // we'll need one for each connective path we put in line here ///////////////////////////////////////////// // (now sets bIsElevStruct itself) /* boolean ReorderAndEstablishXCstruct() // tends to be called after a batch of puts { elevset.SetIsElevStruct(); if (!elevset.bIsElevStruct) return false; System.out.println("WeHAVEelevSubset"); // vcenX = (float)(elevset.elevcenpaths.get(0).pnend.pn.getX() - elevset.elevcenpaths.get(0).pnstart.pn.getX()); // Tsscratchpath.SetUpPathLength(elevset.connsequence.get(0)); // for now! return true; } */ ///////////////////////////////////////////// /* double QCGetPathLength(OnePath op) { Tsscratchpath.SetUpPathLength(op); return Tsscratchpath.GetCumuPathLength(); } */ ///////////////////////////////////////////// /* void FuseNodesElevation(OnePathNode wpnstart, OnePathNode wpnend) { // this will fuse a whole bunch of pieces assert !wpnstart.IsCentrelineNode(); ElevWarpPiece ewp = new ElevWarpPiece(wpnstart, wpnend, opelevarr.get(iopelevarrCEN), ElevWarpPiece.WARP_ZWARP); List<OnePath> nopelevarr = ewp.WarpElevationBatch(opelevarr); assert nopelevarr.size() == opelevarr.size(); for (int i = 0; i < nopelevarr.size(); i++) { RemovePath(opelevarr.get(i)); AddPath(nopelevarr.get(i)); if ((nopelevarr.get(i).linestyle == SketchLineStyle.SLS_CENTRELINE) && (nopelevarr.get(i).plabedl != null)) // prob gratuitous nopelevarr.get(i).UpdateStationLabelsFromCentreline(); } assert wpnstart.pathcount == 0; // should have been removed } */ ///////////////////////////////////////////// SelectedSubsetStructure(SketchDisplay lsketchdisplay) { sketchdisplay = lsketchdisplay; } ///////////////////////////////////////////// String GetFirstSubset() { if (vsselectedsubsetsP.isEmpty()) return null; return vsselectedsubsetsP.iterator().next(); } ///////////////////////////////////////////// boolean SetSubsetVisibleCodeStrings(OnePath op, boolean bAdd) { boolean bpathinsubset = false; for (String ssubset : op.vssubsets) { if (vsselectedsubsets.contains(ssubset)) bpathinsubset = true; } if (bpathinsubset != binversubset) // counts the inverse { op.bpathvisiblesubset = true; op.pnstart.icnodevisiblesubset++; op.pnend.icnodevisiblesubset++; assert bAdd != binversubset; if (elevset.selevsubset != null) elevset.AddRemovePath(op, true); return true; } op.bpathvisiblesubset = false; if (!bAdd && (elevset.selevsubset != null)) // not sure about the bAdd elevset.AddRemovePath(op, false); return false; } ///////////////////////////////////////////// void SetSubsetVisibleCodeStringsT(String lselevsubset, OneSketch sketch) { elevset.Clear(); elevset.selevsubset = lselevsubset; if ((elevset.selevsubset != null) && (elevset.selevsubset.length() > 2)) elevset.bXC = elevset.selevsubset.substring(0, 2).equals("XC"); // yes this should be more organized into a function // set node codes down to be set up by the paths for (OnePathNode opn : sketch.vnodes) opn.icnodevisiblesubset = 0; // set paths according to subset code sketch.bRestrictSubsetCode = !vsselectedsubsets.isEmpty(); int nsubsetpaths = 0; for (OnePath op : sketch.vpaths) { if (SetSubsetVisibleCodeStrings(op, true)) nsubsetpaths++; } elevset.SetIsElevStruct(true); // now scan through the areas and set those in range and their components to visible int nsubsetareas = 0; for (OneSArea osa : sketch.vsareas) nsubsetareas += osa.SetSubsetAttrsA(false, null); // set subset codes on the symbol areas // over-compensate the area; the symbols will spill out. int nccaspills = 0; for (ConnectiveComponentAreas cca : sketch.sksya.vconncom) { cca.bccavisiblesubset = false; for (OneSArea osa : cca.vconnareas) { boolean bareavisiblesubset = osa.bareavisiblesubset; if (bareavisiblesubset) cca.bccavisiblesubset = true; else if (cca.bccavisiblesubset) nccaspills++; } } if (nccaspills != 0) TN.emitMessage("There are " + nccaspills + " symbol area spills beyond subset "); assert sketchdisplay.sketchgraphicspanel.tsketch == sketch; // satisfied by all four calls //TN.emitMessage("Subset paths: " + nsubsetpaths + " areas: " + nsubsetareas); } ///////////////////////////////////////////// void UpdateSingleSubsetSelection(String lsubset) { vsselectedsubsetsP.clear(); vsselectedsubsets.clear(); vsselectedsubsetsP.add(lsubset); vsselectedsubsets.add(lsubset); SetSubsetVisibleCodeStringsT(lsubset, sketchdisplay.sketchgraphicspanel.tsketch); } ///////////////////////////////////////////// void UpdateTreeSubsetSelection(JTree pansksubsetstree) { binversubset = sketchdisplay.miInverseSubset.isSelected(); btransitivesubset = sketchdisplay.miTransitiveSubset.isSelected(); String selevsubset = null; boolean bnotelevsubset = false; TreePath[] tps = pansksubsetstree.getSelectionPaths(); vsselectedsubsetsP.clear(); vsselectedsubsets.clear(); for (int i = (tps != null ? tps.length - 1 : -1); i >= 0; i--) { DefaultMutableTreeNode tn = (DefaultMutableTreeNode)tps[i].getLastPathComponent(); if (tn.getUserObject() instanceof String) { // special case which just handles the string-types in the unattributed (relative to fontcolours) subsets list String ssubset = (String)tn.getUserObject(); vsselectedsubsetsP.add(ssubset); if (tn == sketchdisplay.subsetpanel.sascurrent.dmunattributess) { if (btransitivesubset) vsselectedsubsets.addAll(sketchdisplay.subsetpanel.sascurrent.unattributedss); bnotelevsubset = true; // the set of subsets is not an elevation subset } else if (tn == sketchdisplay.subsetpanel.sascurrent.dmxsectionss) { if (btransitivesubset) vsselectedsubsets.addAll(sketchdisplay.subsetpanel.sascurrent.xsectionss); bnotelevsubset = true; } else { vsselectedsubsets.add(ssubset); bnotelevsubset = (selevsubset != null); // only one of them selevsubset = ssubset; } } else { SubsetAttr sa = (SubsetAttr)tn.getUserObject(); vsselectedsubsetsP.add(sa.subsetname); if (btransitivesubset) { List<SubsetAttr> vssa = new ArrayList<SubsetAttr>(); SelectedSubsetStructure.VRecurseSubsetsdown(vssa, (SubsetAttr)tn.getUserObject()); for (SubsetAttr dsa : vssa) vsselectedsubsets.add(dsa.subsetname); } else vsselectedsubsets.add(sa.subsetname); bnotelevsubset = true; } } if (btransitivesubset) { for (Map.Entry<String, String> mess : sketchdisplay.sketchlinestyle.pthstyleareasigtab.sketchframedefCopied.submapping.entrySet()) { if (!mess.getValue().equals("") && vsselectedsubsets.contains(mess.getValue())) vsselectedsubsets.add(mess.getKey()); } } if (bnotelevsubset || binversubset) selevsubset = null; // get going again SetSubsetVisibleCodeStringsT(selevsubset, sketchdisplay.sketchgraphicspanel.tsketch); sketchdisplay.sketchgraphicspanel.RedoBackgroundView(); } ///////////////////////////////////////////// static void VRecurseSubsetsdown(List<SubsetAttr> vssa, SubsetAttr sa) { if (vssa.contains(sa)) return; int i = vssa.size(); vssa.add(sa); while (i < vssa.size()) { SubsetAttr lsa = vssa.get(i); for (SubsetAttr dsa : vssa.get(i).subsetsdownmap.values()) { if (!vssa.contains(dsa)) vssa.add(dsa); } i++; } } }; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/src/SVGSymbols.java�����������������������������������������������������������0000644�0000000�0000000�00000005575�11762432750�014754� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2006 Martin Green, Julian Todd // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.io.IOException; import java.lang.String; import java.util.List; import java.awt.geom.PathIterator; class SVGSymbols { private float tunnelunit = 0.1F; //length of tunnel unit in meters public SVGSymbols(LineOutputStream los, List<OneSketch> vgsymbolstsketches) throws IOException { WriteHeader(los); for (OneSketch tsketch : vgsymbolstsketches) WriteSymbol(los, tsketch); WriteFooter(los); } // open and close void WriteHeader(LineOutputStream los) throws IOException { TNXML.chconvleng = TNXML.chconvlengWSP; // a complete hack to stop &space; getting in here assert false; // not used los.WriteLine("<?xml version=\"1.0\" standalone=\"no\"?>\n"); los.WriteLine("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\""); los.WriteLine("\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">"); los.WriteLine(TNXML.xcomopen(0, "svg", "xmlns", "http://www.w3.org/2000/svg", "version", "1.1")); los.WriteLine(TNXML.xcomtext(1, "title", "Tunnels Symbols")); los.WriteLine(TNXML.xcomtext(1, "desc", "This file solely contains the symbols for Tunnel, you need a view.svg file to see anything.")); los.WriteLine(TNXML.xcomopen(1, "defs")); } void WriteFooter(LineOutputStream los) throws IOException { los.WriteLine(TNXML.xcomclose(1, "defs")); los.WriteLine(TNXML.xcomclose(0, "svg")); TNXML.chconvleng = TNXML.chconv.length; } void WriteSymbol(LineOutputStream los, OneSketch os) throws IOException { los.WriteLine(TNXML.xcomopen(2, "g","id",os.sketchsymbolname)); for (OnePath op : os.vpaths) WritePath(los, op); los.WriteLine(TNXML.xcomclose(2, "g")); } void WritePath(LineOutputStream los, OnePath op) throws IOException { String classes = new String(SketchLineStyle.shortlinestylenames[op.linestyle]); String d = op.svgdvalue(0.0F, 0.0F); int numparam=4; String parameters[] = {"class", classes, "d", d}; los.WriteLine(TNXML.xcomN(3, "path", parameters, numparam)); } } �����������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/src/RefPathO.java�������������������������������������������������������������0000644�0000000�0000000�00000003562�11762432750�014406� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; ///////////////////////////////////////////// class RefPathO { OnePath op; boolean bFore; RefPathO() {;}; RefPathO(OnePath lop, boolean lbFore) { op = lop; bFore = lbFore; } void ccopy(RefPathO rpo) { op = rpo.op; bFore = rpo.bFore; } RefPathO(RefPathO rpo) { ccopy(rpo); } boolean cequals(RefPathO rpo) { return ((op == rpo.op) && (bFore == rpo.bFore)); } OneSArea GetCrossArea() { return (bFore ? op.kaleft : op.karight); } OnePathNode ToNode() { return (bFore ? op.pnend : op.pnstart); } OnePathNode FromNode() { return (bFore ? op.pnstart : op.pnend); } boolean AdvanceRoundToNode(RefPathO rpmatch) // cycles around the ToNode { assert ToNode() == rpmatch.ToNode(); if (bFore) { bFore = op.bapfrfore; op = op.apforeright; } else { bFore = op.baptlfore; op = op.aptailleft; } assert ToNode() == rpmatch.ToNode(); return cequals(rpmatch); } }; ����������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/src/PathLabelDecode.java������������������������������������������������������0000644�0000000�0000000�00000043555�12261213471�015674� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.io.StringReader; import java.io.IOException; import java.util.List; import java.util.ArrayList; import java.awt.Graphics; import java.awt.FontMetrics; import java.awt.Font; import java.awt.Color; import java.awt.geom.Line2D; //import java.awt.geom.Line2D.Float; import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D.Float; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.awt.Shape; import java.awt.geom.GeneralPath; //////////////////////////////////////////////////////////////////////////////// class PathLabelElement { String text; float xcelloffset = 0.0F; float xcelloffsettop = 0.0F; float ycelloffset = 0.0F; int yiline; boolean bcontinuation = false; boolean btextwidthset = false; boolean btextheightset = false; boolean btextwidthtopset = false; boolean bfontmagnifyset = false; float ftextjustify = -1.0F; // 0.0 left, 0.5 centre, 1.0 right float textwidth; float textheight; float textwidthtop; float fontmagnify = 1.0F; float defaultden; // for carrying over between lines Rectangle2D textrect = null; Shape textshape = null; static int HZT_HORIZONTAL_WIDTH = 0; static int HZT_VERTICAL_WIDTH = 1; static int HZT_TOPLINE_WIDTH = 2; static int HZT_FONTMAGNIFY = 3; //////////////////////////////////////////////////////////////////////////////// PathLabelElement(String ltext, float ldefaultden, float ldefaultftextjustify) { defaultden = ldefaultden; ftextjustify = ldefaultftextjustify; // works out if it is a genuine new line if (ltext.startsWith(";")) { bcontinuation = true; text = ltext.substring(1).trim(); } else text = ltext.trim(); // extract the width coding of %dd/dddd% while (text.indexOf('%') == 0) { if (text.startsWith("%left%")) { ftextjustify = 0.0F; text = text.substring(6).trim(); continue; } if (text.startsWith("%centre%") || text.startsWith("%center%")) { ftextjustify = 0.5F; text = text.substring(8).trim(); continue; } if (text.startsWith("%right%")) { ftextjustify = 1.0F; text = text.substring(7).trim(); continue; } int islashps = text.indexOf('/', 1); int ipercps = text.indexOf('%', 1); if ((ipercps == -1) || (islashps == -1) || !(islashps < ipercps)) break; int numstart = 1; // h = horizontal width // v = vertical width // t = top line width (for doing triangles, as in North Arrow) // f = make the font bigger int ihoriztype = HZT_HORIZONTAL_WIDTH; if (text.charAt(numstart) == 'v') { ihoriztype = HZT_VERTICAL_WIDTH; numstart++; } else if (text.charAt(numstart) == 't') { ihoriztype = HZT_TOPLINE_WIDTH; numstart++; } else if (text.charAt(numstart) == 'h') { ihoriztype = HZT_HORIZONTAL_WIDTH; numstart++; } else if (text.charAt(numstart) == 'f') { ihoriztype = HZT_FONTMAGNIFY; numstart++; } else ihoriztype = HZT_HORIZONTAL_WIDTH; // default case float textdim = -1.0F; String numstr = text.substring(numstart, islashps).trim(); String denstr = text.substring(islashps + 1, ipercps).trim(); // extract the numbers try { float num = (float)Double.parseDouble(numstr); // compilation error with Float if (!denstr.equals("")) // carry the default value over when empty defaultden = (float)Double.parseDouble(denstr); if ((num < 0.0) || (defaultden <= 0.0)) break; textdim = TN.CENTRELINE_MAGNIFICATION * num / defaultden; text = text.substring(ipercps + 1).trim(); } catch (NumberFormatException e) { break; } if (ihoriztype == HZT_HORIZONTAL_WIDTH) { btextwidthset = true; textwidth = textdim; } else if (ihoriztype == HZT_TOPLINE_WIDTH) { btextwidthtopset = true; textwidthtop = textdim; } else if (ihoriztype == HZT_FONTMAGNIFY) { bfontmagnifyset = true; fontmagnify = textdim / TN.CENTRELINE_MAGNIFICATION; } else { assert ihoriztype == HZT_VERTICAL_WIDTH; btextheightset = true; textheight = textdim; } } // then a string of %blackrect% or %whiterect% will make the scalebar pieces rather than write the text } //////////////////////////////////////////////////////////////////////////////// void MakeTextRect(float xpos, float ypos) { textrect = new Rectangle2D.Float(xpos + xcelloffset, ypos - ycelloffset, textwidth, textheight); if ((textwidthtop != textwidth) || (xcelloffset != xcelloffsettop)) { GeneralPath gp = new GeneralPath(); gp.moveTo(xpos + xcelloffsettop, ypos - ycelloffset); gp.lineTo(xpos + xcelloffsettop + textwidthtop, ypos - ycelloffset); gp.lineTo(xpos + xcelloffset + textwidth, ypos + textheight - ycelloffset); gp.lineTo(xpos + xcelloffset, ypos + textheight - ycelloffset); gp.closePath(); textshape = gp; } else textshape = textrect; } }; //////////////////////////////////////////////////////////////////////////////// class PathLabelDecode { // if it's a set of symbols List<String> vlabsymb = new ArrayList<String>(); // the area symbol int iarea_pres_signal = 0; // combobox lookup int barea_pres_signal = SketchLineStyle.ASE_KEEPAREA; // 0 normal, 1 dropdown, 2 hole, 3 kill area, 55 sketchframe // when barea_pres_signal is ASE_SKETCHFRAME, sketchframe SketchFrameDef sketchframedef = null; // when barea_pres_signal is ASE_ZSETRELATIVE float nodeconnzsetrelative = 0.0F; // the label drawing String sfontcode = ""; LabelFontAttr labfontattr = null; Color color = null; // could set a font everywhere with the change of the style float fnodeposxrel = -1.0F; float fnodeposyrel = -1.0F; boolean barrowpresent = false; boolean bboxpresent = false; String drawlab = ""; // values used by a centreline String centrelinetail = null; String centrelinehead = null; String centrelineelev = null; // linesplitting of the drawlabel (using lazy evaluation) List<PathLabelElement> vdrawlablns = new ArrayList<PathLabelElement>(); int yilines = 0; // these could be used for mouse click detection (for dragging of labels) private String drawlab_bak = ""; private Font font_bak = null; Font font = null; private float fnodeposxrel_bak; private float fnodeposyrel_bak; private float x_bak; private float y_bak; float fmdescent; float lnspace; float drawlabxoff; float drawlabyoff; float drawlabxwid; private float drawlabyhei; /*private */float[] arrc = null; // store of the arrow endpoint coords Line2D[] arrowdef = null; Rectangle2D rectdef = null; ///////////////////////////////////////////// PathLabelDecode() { } ///////////////////////////////////////////// public String toString() { assert false; return "tail=" + (centrelinetail == null ? "" : centrelinetail) + " head=" + (centrelinehead == null ? "" : centrelinehead); } ///////////////////////////////////////////// PathLabelDecode(PathLabelDecode o) { iarea_pres_signal = o.iarea_pres_signal; barea_pres_signal = o.barea_pres_signal; if (barea_pres_signal == SketchLineStyle.ASE_SKETCHFRAME) // iarea_pres_signal is the index into the combobox, b is the code. sketchframedef = new SketchFrameDef(o.sketchframedef); nodeconnzsetrelative = o.nodeconnzsetrelative; vlabsymb.addAll(o.vlabsymb); drawlab = o.drawlab; sfontcode = o.sfontcode; fnodeposxrel = o.fnodeposxrel; fnodeposyrel = o.fnodeposyrel; barrowpresent = o.barrowpresent; bboxpresent = o.bboxpresent; centrelinehead = o.centrelinehead; centrelinetail = o.centrelinetail; centrelineelev = o.centrelineelev; } ///////////////////////////////////////////// // reverse of decoding for saving void WriteXML(LineOutputStream los, int indent) throws IOException { WriteXML(los, indent, true); } ///////////////////////////////////////////// boolean IsCentrelineType() { if (centrelinehead != null) { assert ((centrelinetail != null)); assert (centrelineelev == null); return true; } assert (centrelinetail == null); return false; } ///////////////////////////////////////////// void WriteXML(LineOutputStream los, int indent, boolean pathcodes) throws IOException { if (pathcodes) los.WriteLine(TNXML.xcomopen(indent, TNXML.sPATHCODES)); if (IsCentrelineType()) los.WriteLine(TNXML.xcom(indent + 1, TNXML.sCL_STATIONS, TNXML.sCL_TAIL, centrelinetail, TNXML.sCL_HEAD, centrelinehead)); if (centrelineelev != null) los.WriteLine(TNXML.xcom(indent + 1, TNXML.sCL_STATIONS, TNXML.sCL_ELEV, centrelineelev)); if (drawlab != null) { if (barrowpresent || bboxpresent) los.WriteLine(TNXML.xcomtext(indent + 1, TNXML.sPC_TEXT, TNXML.sLTEXTSTYLE, sfontcode, TNXML.sPC_NODEPOSXREL, String.valueOf(fnodeposxrel), TNXML.sPC_NODEPOSYREL, String.valueOf(fnodeposyrel), TNXML.sPC_ARROWPRES, (barrowpresent ? "1" : "0"), TNXML.sPC_BOXPRES, (bboxpresent ? "1" : "0"), TNXML.xmanglxmltext(drawlab))); else los.WriteLine(TNXML.xcomtext(indent + 1, TNXML.sPC_TEXT, TNXML.sLTEXTSTYLE, sfontcode, TNXML.sPC_NODEPOSXREL, String.valueOf(fnodeposxrel), TNXML.sPC_NODEPOSYREL, String.valueOf(fnodeposyrel), TNXML.xmanglxmltext(drawlab))); } // the area signal if (iarea_pres_signal != 0) { if (barea_pres_signal == SketchLineStyle.ASE_SKETCHFRAME) // iarea_pres_signal is the index into the combobox, b is the code. sketchframedef.WriteXML(SketchLineStyle.areasignames[iarea_pres_signal], los, indent + 1); else if (barea_pres_signal == SketchLineStyle.ASE_ZSETRELATIVE) los.WriteLine(TNXML.xcom(indent + 1, TNXML.sPC_AREA_SIGNAL, TNXML.sAREA_PRESENT, SketchLineStyle.areasignames[iarea_pres_signal], TNXML.sASIG_NODECONN_ZSETRELATIVE, String.valueOf(nodeconnzsetrelative))); else los.WriteLine(TNXML.xcom(indent + 1, TNXML.sPC_AREA_SIGNAL, TNXML.sAREA_PRESENT, SketchLineStyle.areasignames[iarea_pres_signal])); } // the symbols for (String rname : vlabsymb) los.WriteLine(TNXML.xcom(indent + 1, TNXML.sPC_RSYMBOL, TNXML.sLRSYMBOL_NAME, rname)); if (pathcodes) los.WriteLine(TNXML.xcomclose(indent, TNXML.sPATHCODES)); } ///////////////////////////////////////////// // used for accessing the fontmetrics function static BufferedImage fm_image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB); static Graphics fm_g = fm_image.getGraphics(); ///////////////////////////////////////////// static float arrowheadlength = 5.0F; static float arrowheadwidth = 3.0F; static float arrowtailstart = 1.5F; ///////////////////////////////////////////// void UpdateLabel(float x, float y, float xend, float yend) { assert ((drawlab != null) && (drawlab.length() != 0)); font = (labfontattr == null ? SketchLineStyle.defaultfontlab : labfontattr.fontlab); // find what aspects of the text need updating boolean blabelchanged = !drawlab.equals(drawlab_bak); boolean bfontchanged = (font_bak != font); boolean bposchanged = ((fnodeposxrel_bak != fnodeposxrel) || (fnodeposyrel_bak != fnodeposyrel) || (x_bak != x) || (y_bak != y)); // break up the label string if (blabelchanged) { vdrawlablns.clear(); int ps = 0; float defaultden = -1.0F; float defaultftextjustify = 0.0F; for (String sple : drawlab.trim().split("\\n")) { sple = sple.replaceAll("\\t", " "); // can't handle tabs properly PathLabelElement ple = new PathLabelElement(sple, defaultden, defaultftextjustify); defaultden = ple.defaultden; defaultftextjustify = ple.ftextjustify; vdrawlablns.add(ple); } drawlab_bak = drawlab; for (PathLabelElement ple : vdrawlablns) { if (ple.bcontinuation && (yilines != 0)) yilines--; ple.yiline = yilines; yilines++; } } // we break up the string into lines FontMetrics fm = (blabelchanged || bfontchanged || bposchanged ? fm_g.getFontMetrics(font) : null); // for using few functions from the given GraphicsAbstraction which may be overwritten but not fully implemented if (blabelchanged || bfontchanged) { lnspace = fm.getAscent() + 0*fm.getLeading(); drawlabyhei = lnspace * (yilines - 1) + fm.getAscent(); fmdescent = fm.getDescent(); drawlabxwid = 0.0F; drawlabyhei = 0.0F; PathLabelElement pleprev = null; for (PathLabelElement ple : vdrawlablns) { if (!ple.btextwidthset) ple.textwidth = fm.stringWidth(ple.text); if (!ple.btextwidthtopset) ple.textwidthtop = ple.textwidth; if (!ple.btextheightset) { ple.textheight = lnspace; if (ple.bfontmagnifyset) ple.textheight = lnspace * ple.fontmagnify; // for when we make the font bigger (for titles, etc) } if (ple.bcontinuation && (pleprev != null)) { ple.xcelloffset = pleprev.xcelloffset + pleprev.textwidth; ple.xcelloffsettop = pleprev.xcelloffsettop + pleprev.textwidthtop; ple.ycelloffset = pleprev.ycelloffset; } else { ple.xcelloffset = 0.0F; ple.xcelloffsettop = 0.0F; ple.ycelloffset = -drawlabyhei; drawlabyhei += ple.textheight; } drawlabxwid = Math.max(drawlabxwid, ple.xcelloffset + ple.textwidth); pleprev = ple; //System.out.println(":" + i + ":" + ple.textwidth + "~" + ple.textheight + " " + ple.text); } font_bak = font; } if (blabelchanged || bfontchanged || bposchanged) { // we find the point for the string drawlabxoff = -drawlabxwid * (fnodeposxrel + 1) / 2; drawlabyoff = drawlabyhei * (fnodeposyrel - 1) / 2; PathLabelElement pleprev = null; for (PathLabelElement ple : vdrawlablns) { ple.MakeTextRect(x + drawlabxoff, y + drawlabyoff); pleprev = ple; } // should be made by merging the textrect rectangles rectdef = new Rectangle2D.Float(x + drawlabxoff, y + drawlabyoff, drawlabxwid, drawlabyhei); fnodeposxrel_bak = fnodeposxrel; fnodeposyrel_bak = fnodeposyrel; x_bak = x; y_bak = y; } // now relay the positions of the lines if (barrowpresent && ((arrc == null) || (arrc[0] != x) || (arrc[1] != xend) || (arrc[2] != y) || (arrc[3] != yend))) { if (arrc == null) arrc = new float[4]; arrc[0] = x; arrc[1] = xend; arrc[2] = y; arrc[3] = yend; if (arrowdef == null) arrowdef = new Line2D.Float[3]; float xv = xend - x; float yv = yend - y; float ln = (float)Math.sqrt(xv * xv + yv * yv); if (ln <= arrowtailstart) return; float xvu = xv / ln; float yvu = yv / ln; arrowdef[0] = new Line2D.Float(x + xvu * arrowtailstart, y + yvu * arrowtailstart, xend, yend); arrowdef[1] = new Line2D.Float(xend - xvu * arrowheadlength + yvu * arrowheadwidth, yend - yvu * arrowheadlength - xvu * arrowheadwidth, xend, yend); arrowdef[2] = new Line2D.Float(xend - xvu * arrowheadlength - yvu * arrowheadwidth, yend - yvu * arrowheadlength + xvu * arrowheadwidth, xend, yend); } } }; // fancy spread stuff (to be refactored later) /* String labspread = TNXML.xrawextracttext(plabel, TNXML.sSPREAD); if (labspread == null) { int ps = plabel.indexOf(TNXML.sLRSYMBOL); int pe = plabel.indexOf("/>"); // standard label drawing // (this shall take <br> and <font> changes) if ((ps == -1) || (pe == -1)) ga.drawString(plabel, (float)pnstart.pn.getX(), (float)pnstart.pn.getY()); return; } , (plabedl.labfontattr == null ? SketchLineStyle.defaultfontlab : plabedl.labfontattr.fontlab) // implements the spread label drawing. if ((nlines == 0) || (labspread.length() < 2)) { ga.drawString(labspread, (float)pnstart.pn.getX(), (float)pnstart.pn.getY()); return; } // update the label points only when necessary. int currlabelcode = (bSplined ? nlines : -nlines); if ((currlabelcode != prevlabelcode) || (vlabelpoints == null) || (vlabelpoints.size() != labspread.length())) { TN.emitMessage("spreading text"); prevlabelcode = currlabelcode; float[] pco = GetCoords(); // not spline for now. // measure lengths float[] lengp = new float[nlines + 1]; lengp[0] = 0.0F; for (int i = 1; i <= nlines; i++) { float xv = pco[i * 2] - pco[i * 2 - 2]; float yv = pco[i * 2 + 1] - pco[i * 2 - 1]; lengp[i] = lengp[i - 1] + (float)Math.sqrt(xv * xv + yv * yv); } // make up the labelpoints array. if (vlabelpoints == null) vlabelpoints = new ArrayList<Point2D>(); vlabelpoints.setSize(labspread.length()); // appears not to be a function in ArrayList // find the locations. int il = 1; for (int j = 0; j < labspread.length(); j++) { float lenb = lengp[nlines] * j / (labspread.length() - 1); while ((il < nlines) && (lengp[il] < lenb)) il++; // find the lambda along this line. float lamden = lengp[il] - lengp[il - 1]; float lam = (lamden != 0.0F ? (lengp[il] - lenb) / lamden : 0.0F); float tx = lam * pco[il * 2 - 2] + (1.0F - lam) * pco[il * 2]; float ty = lam * pco[il * 2 - 1] + (1.0F - lam) * pco[il * 2 + 1]; if (vlabelpoints.get(j) == null) vlabelpoints.set(j, new Point2D.Float()); vlabelpoints.get(j).setLocation(tx, ty); } } for (int i = 0; i < labspread.length(); i++) { Point2D pt = vlabelpoints.get(i); ga.drawString(labspread.substring(i, i + 1), (float)pt.getX(), (float)pt.getY()); } */ ���������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/src/Vec3.java�����������������������������������������������������������������0000644�0000000�0000000�00000013235�12261213471�013524� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; // // // Vec3 // // class Vec3 { public float x; public float y; public float z; ///////////////////////////////////////////// public Vec3() { x = 0.0F; y = 0.0F; z = 0.0F; } ///////////////////////////////////////////// public String toString() { return String.valueOf(x) + " " + String.valueOf(y) + " " + String.valueOf(z); } ///////////////////////////////////////////// Vec3(String w0, String w1, String w2) { SetXYZ(Float.parseFloat(w0), Float.parseFloat(w1), Float.parseFloat(w2)); } ///////////////////////////////////////////// public Vec3(float lx, float ly, float lz) { SetXYZ(lx, ly, lz); } ///////////////////////////////////////////// public boolean isZero() { if (x == 0 && y == 0 && z == 0) return true; else return false; } ///////////////////////////////////////////// public float Dot(Vec3 a) { return x * a.x + y * a.y + z * a.z; } ///////////////////////////////////////////// public void Diff(Vec3 a, Vec3 b) { x = b.x - a.x; y = b.y - a.y; z = b.z - a.z; } ///////////////////////////////////////////// public void Sum(Vec3 a, Vec3 b) { x = b.x + a.x; y = b.y + a.y; z = b.z + a.z; } ///////////////////////////////////////////// public void PlusEquals(Vec3 a) { x += a.x; y += a.y; z += a.z; } ///////////////////////////////////////////// public void TimesEquals(float f) { x *= f; y *= f; z *= f; } ///////////////////////////////////////////// public void Negate() { x = -x; y = -y; z = -z; } ///////////////////////////////////////////// public void Cross(Vec3 a, Vec3 b) { x = a.y * b.z - a.z * b.y; y = -a.x * b.z + a.z * b.x; z = a.x * b.y - a.y * b.x; } ///////////////////////////////////////////// public float Len() { float sqlen = x * x + y * y + z * z; return((float)(Math.sqrt(sqlen))); } ///////////////////////////////////////////// public void Norm() { float sqlen = x * x + y * y + z * z; float fac = (sqlen == 0.0F ? 1.0F : (float)(1.0F / Math.sqrt(sqlen))); x *= fac; y *= fac; z *= fac; } ///////////////////////////////////////////// public void SetXYZ(float lx, float ly, float lz) { x = lx; y = ly; z = lz; } ///////////////////////////////////////////// public void SetXYZ(Vec3 a) { SetXYZ(a.x, a.y, a.z); } ///////////////////////////////////////////// public int ConvCompress(boolean bNegate) { float sqlen = x * x + y * y + z * z; float fac = (sqlen == 0.0F ? 1.0F : (float)(1.0F / Math.sqrt(sqlen))) * (bNegate ? -1 : 1); float nx = x * fac; float ny = y * fac; float nz = z * fac; int inx = Math.max(0, Math.min(255, (int)(nx * 127 + (nx > 0.0F ? 0.5F : -0.5F)) + 128)); int iny = Math.max(0, Math.min(255, (int)(ny * 127 + (ny > 0.0F ? 0.5F : -0.5F)) + 128)); int inz = Math.max(0, Math.min(255, (int)(nz * 127 + (nz > 0.0F ? 0.5F : -0.5F)) + 128)); int insz = (nz >= 0.0F ? 0 : 128); int res = (insz | (inx << 8) | (iny << 16) | (inz << 24)); return res; } ///////////////////////////////////////////// void ConvDecompress(int c) { int inx = (255 & (c >> 8)); int iny = (255 & (c >> 16)); int inz = (255 & (c >> 24)); x = (inx - 128) / 127.0F; y = (iny - 128) / 127.0F; z = (inz - 128) / 127.0F; Norm(); } ///////////////////////////////////////////// static int ConvCompressInvert(int c) { int inx = (255 & (c >> 8)); int iny = (255 & (c >> 16)); int inz = (255 & (c >> 24)); int iinx = 256 -inx; int iiny = 256 - iny; int iinz = 256 - inz; int iinsz = (((c & 128) == 0) ? 128 : 0); int res = (iinsz | (iinx << 8) | (iiny << 16) | (iinz << 24)); return res; } ///////////////////////////////////////////// public void SetAlong(float lambda, Vec3 vf, Vec3 vt) { float mlam = 1.0F - lambda; SetXYZ(vf.x * mlam + vt.x * lambda, vf.y * mlam + vt.y * lambda, vf.z * mlam + vt.z * lambda); } ///////////////////////////////////////////// public void SetOnSphere(float fx, float fy) { float dsq = fx * fx + fy * fy; if (dsq > 1.0F) { float d = (float)(Math.sqrt(dsq)); SetXYZ(fx / d, fy / d, 0.0F); } else SetXYZ(fx, fy, (float)(Math.sqrt(1.0F - dsq))); } ///////////////////////////////////////////// public static double Arg(double x, double y) { double theta; if (x != 0.0F) { theta = Math.atan(y / x); if (x <= 0.0F) theta += Math.PI; } else { if (y >= 0.0F) theta = Math.PI / 2; else theta = -Math.PI / 2; } if (theta < 0.0F) theta += Math.PI * 2; if (theta > Math.PI * 2) theta -= Math.PI * 2; return theta; } ///////////////////////////////////////////// public static float DegArg(double x, double y) { return (float)(Math.toDegrees(Arg(x, y))); } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/src/ConnectiveComponentAreas.java���������������������������������������������0000644�0000000�0000000�00000007427�11762432750�017676� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2002 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// package Tunnel; import java.awt.geom.GeneralPath; import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.AffineTransform; import java.awt.geom.Area; import java.awt.Shape; import java.util.ArrayList; import java.util.SortedSet; import java.util.TreeSet; import java.util.List; import java.util.ArrayList; // // // // // manages the area sharing of symbols ///////////////////////////////////////////// // corresponds to saarea of the ossameva class ConnectiveComponentAreas { List<OnePath> vconnpaths; List<OnePath> vconnpathsrem; SortedSet<OneSArea> vconnareas; Area saarea = null; // index in SketchSymbolAreas of overlapping connective component areas List<ConnectiveComponentAreas> overlapcomp = new ArrayList<ConnectiveComponentAreas>(); boolean bHasrendered = false; // used to help the ordering in the quality rendering boolean bccavisiblesubset = false; MutualComponentArea pvconncommutual = null; // used to link into vconncommutual (each area will be in exactly one) ///////////////////////////////////////////// ConnectiveComponentAreas(List<OnePath> lvconnpaths, List<OnePath> lvconnpathsrem, SortedSet<OneSArea> lvconnareas) { vconnpaths = new ArrayList<OnePath>(lvconnpaths); vconnpathsrem = new ArrayList<OnePath>(lvconnpathsrem); vconnareas = new TreeSet<OneSArea>(lvconnareas); // now make the combined area here saarea = new Area(); // if there's only one area, do we need to duplicate it (will need to if there are two, because we don't want to affect the original area) for (OneSArea osa : vconnareas) { if ((osa.aarea != null) && ((osa.iareapressig == SketchLineStyle.ASE_KEEPAREA) || (osa.iareapressig == SketchLineStyle.ASE_VERYSTEEP))) saarea.add(osa.aarea); osa.ccalist.add(this); } } // dummy holder ConnectiveComponentAreas(boolean bdum) {;} ///////////////////////////////////////////// boolean Overlaps(ConnectiveComponentAreas cca) { for (OneSArea osa : vconnareas) { if (cca.vconnareas.contains(osa)) return true; } return false; } ///////////////////////////////////////////// void paintWsymbols(GraphicsAbstraction ga) { // the clip has to be reset for printing otherwise it crashes. // this is not how it should be according to the spec for (OnePath op : vconnpaths) { for (OneSSymbol msymbol : op.vpsymbols) { if (msymbol.ssb.symbolareafillcolour == null) { if (msymbol.ssb.bTrimByArea) ga.startSymbolClip(this); msymbol.paintW(ga, false, true); if (msymbol.ssb.bTrimByArea) ga.endClip(); } // Should this have a start/end symbols around it? else ga.fillArea(this, msymbol.ssb.symbolareafillcolour); } // do the text that's on this line //if ((op.linestyle == SketchLineStyle.SLS_CONNECTIVE) && (op.plabedl != null) && (op.plabedl.labfontattr != null)) // op.paintLabel(ga, null); } } }; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/j.bat�������������������������������������������������������������������������0000644�0000000�0000000�00000000557�12261213471�012216� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������dir/b symbols > symbols\listdir.txt dir/b tutorials > tutorials\listdir.txt "C:\Program Files\Java\jdk1.6.0_26\bin\jar" cmf tunnelmanifest.txt tunnel.jar Tunnel symbols/*.xml symbols/*.html symbols/listdir.txt tutorials/*.* tutorials/listdir.txt REM "C:\Program Files\Java\jdk1.6.0_26\bin\jar" i tunnel.jar REM "C:\Program Files\Java\jdk1.6.0\bin\jar" tf tunnel.jar �������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/tutorials/��������������������������������������������������������������������0000755�0000000�0000000�00000000000�12066375447�013333� 5����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/tutorials/010_lesson_one.xml��������������������������������������������������0000644�0000000�0000000�00000007612�12066375447�016607� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-06 16:36:36"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="connective"> <pathcodes> <pctext style="area" nodeposxrel="-1.0" nodeposyrel="-1.0">Drawing&space;and&space;selecting</pctext> </pathcodes> <pt X="57.0" Y="94.0"/> <pt X="55.036617" Y="98.58618"/> </skpath> <skpath from="2" to="3" linestyle="connective"> <pathcodes> <pctext style="entrance" nodeposxrel="-1.0" nodeposyrel="1.0">TunnelX&space;is&space;best&space;controlled&space;using&space;a&space;3&space;button&space;mouse&space;&newline;with&space;a&space;scrollwheel.</pctext> </pathcodes> <pt X="57.8914" Y="131.41614"/> <pt X="52.895535" Y="139.26678"/> </skpath> <skpath from="4" to="5" linestyle="connective"> <pathcodes> <pctext style="entrance" nodeposxrel="-1.0" nodeposyrel="1.0">Click&space;with&space;the&space;Left-mouse&space;button&space;anywhere&space;on&space;this&space;&newline;pane&space;and&space;keep&space;clicking&space;to&space;draw&space;a&space;scribble,&space;like&space;this:</pctext> </pathcodes> <pt X="52.895535" Y="183.51587"/> <pt X="57.8914" Y="175.66522"/> </skpath> <skpath from="6" to="7" linestyle="connective"> <pathcodes> <pctext style="entrance" nodeposxrel="-1.0" nodeposyrel="1.0">Try&space;drawing&space;some&space;more&space;paths.&newline;&newline;A&space;path&space;is&space;coloured&space;pink&space;when&space;it&space;is&space;selected.&newline;&newline;Click&space;the&space;Right-mouse&space;button&space;on&space;any&space;path&space;to&space;select&space;it.&newline;&newline;When&space;a&space;path&space;is&space;selected&space;you&space;can&space;delete&space;it&space;by&space;clicking&space;on&space;&newline;the&space;[Delete]&space;button&space;in&space;the&space;row&space;of&space;five&space;buttons:&space;&newline;.&space;[Reflect]&space;.&space;[Fuse]&space;.&space;[Component]&space;.&space;[Back]&space;.&space;[Delete]&space;.</pctext> </pathcodes> <pt X="55.26095" Y="345.72375"/> <pt X="54.341183" Y="371.4771"/> </skpath> <skpath from="8" to="9" linestyle="connective"> <pt X="56.235004" Y="54.06114"/> <pt X="54.258526" Y="60.649395"/> </skpath> <skpath from="10" to="11" linestyle="connective"> <pt X="406.2383" Y="537.12616"/> <pt X="400.9677" Y="544.3732"/> </skpath> <skpath from="12" to="13" linestyle="wall"> <pt X="83.74007" Y="224.50206"/> <pt X="95.02857" Y="230.58049"/> <pt X="108.05378" Y="225.3704"/> <pt X="122.815674" Y="229.71214"/> <pt X="115.8689" Y="248.81577"/> <pt X="90.686844" Y="247.07907"/> <pt X="68.109825" Y="244.47403"/> <pt X="74.188255" Y="236.65892"/> <pt X="82.87172" Y="243.60568"/> <pt X="84.60841" Y="258.36758"/> <pt X="107.18543" Y="260.97263"/> <pt X="118.47394" Y="267.05106"/> <pt X="96.76527" Y="269.6561"/> <pt X="93.29188" Y="277.47122"/> </skpath> <skpath from="14" to="15" linestyle="connective"> <pathcodes> <pctext style="entrance" nodeposxrel="-1.0" nodeposyrel="1.0">Now&space;hold&space;the&space;Shift-key&space;on&space;the&space;keyboard&space;down&space;as&space;you&space;&newline;click&space;the&space;left&space;mouse&space;button&space;again&space;to&space;finish&space;the&space;path.</pctext> </pathcodes> <pt X="55.40809" Y="304.73605"/> <pt X="58.40527" Y="295.6373"/> </skpath> <skpath from="16" to="17" linestyle="connective"> <pathcodes> <pctext style="passage" nodeposxrel="-1.0" nodeposyrel="1.0">Now&space;close&space;this&space;window&space;and&space;go&space;&newline;to&space;the&space;next&space;lesson</pctext> </pathcodes> <pt X="51.066353" Y="495.1535"/> <pt X="55.40809" Y="482.1283"/> </skpath> </sketch> </tunnelxml> ����������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/tutorials/020_lesson_two.xml��������������������������������������������������0000644�0000000�0000000�00000003707�12066375447�016641� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-06 16:40:43"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="connective"> <pathcodes> <pctext style="cave" nodeposxrel="-1.0" nodeposyrel="1.0">Hold&space;the&space;Control-key&space;down;&space;&newline;click&space;your&space;Middle-mouse&space;button&space;&newline;on&space;the&space;tiny&space;writing&space;below;&newline;and&space;drag&space;to&space;the&space;right&space;&newline;to&space;zoom</pctext> </pathcodes> <pt X="64.62402" Y="45.814632"/> <pt X="55.036617" Y="98.58618"/> </skpath> <skpath from="2" to="3" linestyle="connective"> <pathcodes> <pctext style="entrance" nodeposxrel="-1.0" nodeposyrel="1.0">The&space;scroll-wheel&space;can&space;also&space;zoom&space;&newline;into&space;and&space;out&space;from&space;the&space;place&space;where&space;&newline;the&space;Mouse-cursor&space;is&space;pointing.&newline;&newline;The&space;Middle-mouse&space;button&space;on&space;its&space;&newline;own&space;(without&space;the&space;Conrol-key)&space;&newline;will&space;drag&space;the&space;view&space;position.</pctext> </pathcodes> <pt X="577.93884" Y="447.88055"/> <pt X="564.5429" Y="470.20715"/> </skpath> <skpath from="4" to="5" linestyle="connective"> <pathcodes> <pctext style="qm" nodeposxrel="-1.0" nodeposyrel="1.0">Once&space;you&space;have&space;mastered&space;these&space;controls,&space;&newline;close&space;this&space;window&space;and&space;go&space;to&space;the&space;next&space;lesson</pctext> </pathcodes> <pt X="566.524" Y="575.34766"/> <pt X="556.5761" Y="587.28503"/> </skpath> <skpath from="6" to="7" linestyle="connective"> <pt X="2951.8787" Y="1212.8207"/> <pt X="2984.3196" Y="1147.9388"/> </skpath> </sketch> </tunnelxml> ���������������������������������������������������������tunnelx-20140102.orig/tutorials/810_scalebars.xml���������������������������������������������������0000644�0000000�0000000�00000007424�12066375447�016413� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2011-08-08 21:47:40"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="1" to="0" linestyle="connective"> <pathcodes> <pctext style="area" nodeposxrel="-1.0" nodeposyrel="-1.0">%10/1.0000%%whiterect%&newline;;%10/%%blackrect%&newline;;%10/%%whiterect%&newline;;%10/%%blackrect%&newline;;%10/%%whiterect%&newline;%v1.0/1%&newline;%10/%0m&newline;;%10/%10m&newline;;%10/%20m&newline;;%10/%30m&newline;;%10/%40m&newline;;%10/%50m</pctext> </pathcodes> <pt X="150.66275" Y="-70.87606"/> <pt X="57.0" Y="94.0"/> </skpath> <skpath from="2" to="3" linestyle="connective"> <pathcodes> <pctext style="area" nodeposxrel="-1.0" nodeposyrel="-1.0">%0/1.0000%%v0/%&newline;;%50/%%v1/%%whiterect%&newline;%1/%%v0.5/%&newline;;%1/%%v0.5/%%blackrect%&newline;;%1/%&newline;;%1/%%v0.5/%%blackrect%&newline;;%1/%&newline;;%5/%%v0.5/%%blackrect%&newline;;%5/%%v1/%&newline;;%5/%%v0.5/%%blackrect%&newline;;%5/%%v1/%&newline;;%5/%%v0.5/%%blackrect%&newline;;%5/%%v1/%&newline;;%5/%%v0.5/%%blackrect%&newline;;%5/%%v1/%&newline;;%5/%%v0.5/%%blackrect%&newline;%1/%%v0.5/%%blackrect%&newline;;%1/%&newline;;%1/%%v0.5/%%blackrect%&newline;;%1/%&newline;;%1/%%v0.5/%%blackrect%&newline;;%5/%&newline;;%5/%%v0.5/%%blackrect%&newline;;%5/%&newline;;%5/%%v0.5/%%blackrect%&newline;;%5/%&newline;;%5/%%v0.5/%%blackrect%&newline;;%5/%&newline;;%5/%%v0.5/%%blackrect%&newline;%v0.8/%&newline;%4.5/%0m&newline;;%5/%5m&newline;;%10/%10m&newline;;%10/%20m&newline;;%10/%30m&newline;;%10/%40m&newline;;%10/%50m</pctext> </pathcodes> <pt X="167.91783" Y="60.693962"/> <pt X="58.99511" Y="145.89095"/> </skpath> <skpath from="4" to="5" linestyle="connective"> <pathcodes> <pctext style="area" nodeposxrel="-1.0" nodeposyrel="-1.0">N&newline;%t1/0.1%%v0/%%h0/%&newline;;%v3/%%t0/%%h2/%%whiterect%&newline;%t1/%%v0/%%h0/%&newline;;%v3/%%t0/%%h1/%%blackrect%</pctext> </pathcodes> <pt X="150.66275" Y="154.51848"/> <pt X="44.975353" Y="233.24481"/> </skpath> <skpath from="6" to="7" linestyle="connective"> <pathcodes> <pctext style="area" nodeposxrel="-1.0" nodeposyrel="1.0">%10/3%%v50/%%blackrect%&newline;;1800m&newline;%10/%%v50.0/%%whiterect%&newline;;1600m&newline;%10/%%v50/%%blackrect%&newline;;1500m&newline;%10/%%v50.0/%%whiterect%&newline;;1400m&newline;%10/%%v50/%%blackrect%&newline;;1300m&newline;%10/%%v50.0/%%whiterect%&newline;;1200m&newline;%10/%%v50/%%blackrect%&newline;;1100m&newline;%10/%%v0/%&newline;;1700m</pctext> </pathcodes> <pt X="890.3953" Y="-103.19948"/> <pt X="628.95105" Y="220.76408"/> </skpath> <skpath from="8" to="9" linestyle="connective"> <pathcodes> <pctext style="area" nodeposxrel="-1.0" nodeposyrel="0.0">%1/1%%v50.0/%&space;&newline;;%15/%%v52.0/%1550m&newline;;%10/%%v50.0/%&space;&newline;%1/%%v50.0/%&newline;;%15/%%v52.0/%1500m&newline;;%10/%%v50.0/%%blackrect%&space;&space;&space;&space;&newline;%1/%%v50.0/%&newline;;%15/%%v52.0/%1450m&space;&newline;;%10/%%v50.0/%%whiterect%&space;&space;&newline;%1/%%v50.0/%&newline;;%15/%%v52.0/%1400m&newline;;%10/%%v50.0/%%blackrect%&space;&space;&space;&space;&newline;%1/%%v50.0/%&newline;;%15/%%v52.0/%1350m&space;&newline;;%10/%%v50.0/%%whiterect%&space;&space;&newline;%1/%%v50.0/%&newline;;%15/%%v52.0/%1300m&newline;;%10/%%v50.0/%%blackrect%&space;&space;&space;&space;&newline;%1/%%v50.0/%&newline;;%15/%%v52.0/%1250m&newline;;%10/%%v50.0/%%whiterect%&space;&space;&newline;%1/%%v50.0/%&newline;;%15/%%v52.0/%1200m&newline;;%10/%%v50.0/%%blackrect%</pctext> </pathcodes> <pt X="1260.0117" Y="-32.852516"/> <pt X="1098.3282" Y="223.78796"/> </skpath> </sketch> </tunnelxml> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/tutorials/050_building_areas.xml����������������������������������������������0000644�0000000�0000000�00000025377�12066375447�017427� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:08"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="connective"> <pt X="960.863" Y="860.9993"/> <pt X="951.76526" Y="869.26996"/> </skpath> <skpath from="2" to="3" linestyle="wall" splined="1"> <pt X="678.95605" Y="639.66364"/> <pt X="687.19415" Y="644.09955"/> <pt X="696.066" Y="646.0007"/> </skpath> <skpath from="3" to="4" linestyle="wall" splined="1"> <pt X="696.066" Y="646.0007"/> <pt X="705.6724" Y="645.6577"/> <pt X="715.33386" Y="645.6577"/> </skpath> <skpath from="5" to="6" linestyle="detail"> <pt X="724.44324" Y="654.7671"/> <pt X="709.537" Y="666.3608"/> </skpath> <skpath from="4" to="7" linestyle="estwall" splined="1"> <pt X="715.33386" Y="645.6577"/> <pt X="705.9485" Y="634.34"/> <pt X="712.8495" Y="619.9859"/> <pt X="730.7922" Y="615.2932"/> <pt X="749.01086" Y="620.814"/> <pt X="751.49524" Y="632.4078"/> <pt X="743.49005" Y="645.10565"/> <pt X="741.8338" Y="647.0379"/> </skpath> <skpath from="2" to="8" linestyle="connective"> <pt X="678.95605" Y="639.66364"/> <pt X="677.9895" Y="644.1771"/> </skpath> <skpath from="9" to="10" linestyle="estwall" splined="1"> <pt X="767.7817" Y="679.05865"/> <pt X="781.81006" Y="679.12494"/> <pt X="789.6441" Y="679.3071"/> </skpath> <skpath from="5" to="11" linestyle="detail"> <pt X="724.44324" Y="654.7671"/> <pt X="735.7609" Y="666.63684"/> </skpath> <skpath from="12" to="13" linestyle="detail" splined="1"> <pt X="646.5524" Y="633.7757"/> <pt X="647.30994" Y="641.8087"/> <pt X="633.912" Y="647.12103"/> <pt X="612.1166" Y="648.0572"/> <pt X="600.5386" Y="645.64795"/> <pt X="599.05634" Y="632.45306"/> </skpath> <skpath from="14" to="6" linestyle="detail"> <pt X="703.834" Y="668.5581"/> <pt X="709.537" Y="666.3608"/> </skpath> <skpath from="15" to="9" linestyle="wall" splined="1"> <pt X="718.2957" Y="680.6285"/> <pt X="724.44324" Y="681.543"/> <pt X="743.7661" Y="680.99097"/> <pt X="767.7817" Y="679.05865"/> </skpath> <skpath from="16" to="2" linestyle="wall" splined="1"> <pt X="660.2602" Y="635.33887"/> <pt X="668.5623" Y="636.1311"/> <pt X="678.95605" Y="639.66364"/> </skpath> <skpath from="17" to="18" linestyle="detail"> <pt X="705.4737" Y="651.6147"/> <pt X="706.50055" Y="650.3504"/> </skpath> <skpath from="19" to="20" linestyle="wall" splined="1"> <pt X="626.35846" Y="675.14087"/> <pt X="627.4427" Y="675.3658"/> <pt X="621.9115" Y="677.7706"/> <pt X="610.96936" Y="677.0492"/> <pt X="605.9191" Y="680.416"/> <pt X="607.7228" Y="682.9411"/> <pt X="612.5564" Y="683.14606"/> </skpath> <skpath from="21" to="9" linestyle="pitchbound" splined="1"> <pt X="773.0264" Y="647.866"/> <pt X="780.47955" Y="657.52747"/> <pt X="778.8233" Y="668.2931"/> <pt X="767.7817" Y="679.05865"/> </skpath> <skpath from="22" to="19" linestyle="wall" splined="1"> <pt X="655.79504" Y="660.3082"/> <pt X="652.0303" Y="669.06793"/> <pt X="647.0615" Y="672.38043"/> <pt X="634.63965" Y="674.8648"/> <pt X="626.35846" Y="675.14087"/> </skpath> <skpath from="23" to="22" linestyle="wall" splined="1"> <pt X="572.49396" Y="651.704"/> <pt X="603.5454" Y="653.6051"/> <pt X="630.1609" Y="654.23883"/> <pt X="655.79504" Y="660.3082"/> </skpath> <skpath from="24" to="3" linestyle="pitchbound" splined="1"> <pt X="685.92676" Y="670.08136"/> <pt X="684.02563" Y="662.4769"/> <pt X="684.65936" Y="655.5062"/> <pt X="696.066" Y="646.0007"/> </skpath> <skpath from="25" to="14" linestyle="detail"> <pt X="718.9555" Y="676.0278"/> <pt X="703.834" Y="668.5581"/> </skpath> <skpath from="26" to="24" linestyle="wall" splined="1"> <pt X="670.65924" Y="664.8014"/> <pt X="685.92676" Y="670.08136"/> </skpath> <skpath from="22" to="26" linestyle="ceilingbound" splined="1"> <pt X="655.79504" Y="660.3082"/> <pt X="660.31146" Y="663.5471"/> <pt X="670.65924" Y="664.8014"/> </skpath> <skpath from="15" to="25" linestyle="invisible" splined="1"> <pt X="718.2957" Y="680.6285"/> <pt X="718.9555" Y="676.0278"/> </skpath> <skpath from="27" to="28" linestyle="wall" splined="1"> <pt X="669.9729" Y="666.30756"/> <pt X="665.5563" Y="672.38043"/> <pt X="656.99896" Y="678.1773"/> <pt X="642.0928" Y="681.4898"/> </skpath> <skpath from="29" to="11" linestyle="detail"> <pt X="721.13074" Y="675.47015"/> <pt X="735.7609" Y="666.63684"/> </skpath> <skpath from="7" to="4" linestyle="pitchbound" splined="1"> <pt X="741.8338" Y="647.0379"/> <pt X="730.6155" Y="649.2463"/> <pt X="721.1418" Y="648.3353"/> <pt X="715.33386" Y="645.6577"/> </skpath> <skpath from="24" to="15" linestyle="wall" splined="1"> <pt X="685.92676" Y="670.08136"/> <pt X="697.1152" Y="674.642"/> <pt X="718.2957" Y="680.6285"/> </skpath> <skpath from="7" to="21" linestyle="wall" splined="1"> <pt X="741.8338" Y="647.0379"/> <pt X="752.0473" Y="647.0379"/> <pt X="764.4692" Y="647.31396"/> <pt X="773.0264" Y="647.866"/> </skpath> <skpath from="30" to="14" linestyle="detail"> <pt X="711.668" Y="660.3597"/> <pt X="703.834" Y="668.5581"/> </skpath> <skpath from="6" to="29" linestyle="detail"> <pt X="709.537" Y="666.3608"/> <pt X="721.13074" Y="675.47015"/> </skpath> <skpath from="28" to="20" linestyle="wall" splined="1"> <pt X="642.0928" Y="681.4898"/> <pt X="626.6345" Y="682.87"/> <pt X="619.73346" Y="683.42206"/> <pt X="612.5564" Y="683.14606"/> </skpath> <skpath from="12" to="16" linestyle="wall" splined="1"> <pt X="646.5524" Y="633.7757"/> <pt X="660.2602" Y="635.33887"/> </skpath> <skpath from="31" to="30" linestyle="detail"> <pt X="714.7652" Y="657.62683"/> <pt X="714.9474" Y="660.1775"/> <pt X="711.668" Y="660.3597"/> </skpath> <skpath from="32" to="10" linestyle="invisible" splined="1"> <pt X="792.1947" Y="647.97095"/> <pt X="793.10565" Y="659.9953"/> <pt X="792.92346" Y="664.3678"/> <pt X="791.8303" Y="671.2909"/> <pt X="789.6441" Y="679.3071"/> </skpath> <skpath from="13" to="12" linestyle="wall" splined="1"> <pt X="599.05634" Y="632.45306"/> <pt X="604.213" Y="632.76996"/> <pt X="636.2952" Y="633.6192"/> <pt X="646.5524" Y="633.7757"/> </skpath> <skpath from="29" to="25" linestyle="detail"> <pt X="721.13074" Y="675.47015"/> <pt X="718.9555" Y="676.0278"/> </skpath> <skpath from="30" to="17" linestyle="detail"> <pt X="711.668" Y="660.3597"/> <pt X="705.4737" Y="651.6147"/> </skpath> <skpath from="33" to="23" linestyle="invisible" splined="1"> <pt X="576.29614" Y="632.0592"/> <pt X="572.49396" Y="651.704"/> </skpath> <skpath from="19" to="28" linestyle="detail" splined="1"> <pt X="626.35846" Y="675.14087"/> <pt X="630.7751" Y="677.0731"/> <pt X="637.124" Y="678.45337"/> <pt X="642.0928" Y="681.4898"/> </skpath> <skpath from="31" to="34" linestyle="detail"> <pt X="714.7652" Y="657.62683"/> <pt X="720.9596" Y="653.8009"/> </skpath> <skpath from="33" to="13" linestyle="wall" splined="1"> <pt X="576.29614" Y="632.0592"/> <pt X="599.05634" Y="632.45306"/> </skpath> <skpath from="21" to="32" linestyle="estwall" splined="1"> <pt X="773.0264" Y="647.866"/> <pt X="782.9032" Y="647.2422"/> <pt X="792.1947" Y="647.97095"/> </skpath> <skpath from="34" to="5" linestyle="detail"> <pt X="720.9596" Y="653.8009"/> <pt X="724.44324" Y="654.7671"/> </skpath> <skpath from="18" to="31" linestyle="detail"> <pt X="706.50055" Y="650.3504"/> <pt X="714.2297" Y="655.31915"/> <pt X="714.7652" Y="657.62683"/> </skpath> <skpath from="35" to="36" linestyle="connective"> <pathcodes> <pctext style="entrance" nodeposxrel="-1.0" nodeposyrel="1.0" arrowpres="1" boxpres="0">This&space;path&space;isn&apostrophe;t&space;attached.</pctext> </pathcodes> <pt X="693.4685" Y="694.9275"/> <pt X="671.71985" Y="668.1599"/> </skpath> <skpath from="37" to="38" linestyle="connective"> <pathcodes> <pctext style="entrance" nodeposxrel="1.0" nodeposyrel="1.0" arrowpres="1" boxpres="0">This&space;path&space;is&space;&newline;attached&space;&newline;with&space;a&space;hook&newline;(zoom&space;in&space;and&space;&newline;[stroke&space;<<]&space;&newline;to&space;look)</pctext> </pathcodes> <pt X="595.59955" Y="663.55927"/> <pt X="621.1124" Y="672.7606"/> </skpath> <skpath from="39" to="40" linestyle="connective"> <pathcodes> <pctext style="entrance" nodeposxrel="-1.0" nodeposyrel="1.0">Click&space;on&space;the&space;[Update&space;Areas]&space;button.&newline;&newline;This&space;generates&space;the&space;areas&space;from&space;the&space;way&space;the&space;paths&space;&newline;are&space;joined.&space;&space;&newline;&newline;Hold&space;the&space;Shift-key&space;down&space;and&space;Right-mouse&space;click&space;in&newline;an&space;area&space;to&space;select&space;all&space;the&space;paths&space;that&space;are&space;its&space;boundary</pctext> </pathcodes> <pt X="521.9412" Y="481.11353"/> <pt X="519.9372" Y="490.9516"/> </skpath> <skpath from="41" to="42" linestyle="connective"> <pathcodes> <pctext style="entrance" nodeposxrel="-1.0" nodeposyrel="1.0">There&space;are&space;two&space;mistakes&space;with&space;this&space;diagram</pctext> </pathcodes> <pt X="522.5749" Y="588.2091"/> <pt X="526.37714" Y="593.27875"/> </skpath> <skpath from="43" to="44" linestyle="connective"> <pathcodes> <pctext style="entrance" nodeposxrel="-1.0" nodeposyrel="1.0">You&space;will&space;have&space;to&space;delete&space;and&space;redraw&space;each&space;&newline;bad&space;path&space;--&space;attaching&space;to&space;the&space;nodes&space;properly&space;--&space;&newline;and&space;then&space;click&space;on&space;[Update&space;Areas]&space;again&space;to&space;&newline;fix&space;the&space;mistake.</pctext> </pathcodes> <pt X="530.7322" Y="760.6882"/> <pt X="538.9703" Y="756.886"/> </skpath> <skpath from="45" to="46" linestyle="connective"> <pathcodes> <pctext style="area" nodeposxrel="-1.0" nodeposyrel="0.0">Areas&space;are&space;made&space;from&space;paths&space;&newline;which&space;join&space;correctly</pctext> </pathcodes> <pt X="505.46494" Y="427.88257"/> <pt X="498.3313" Y="384.64484"/> </skpath> <skpath from="47" to="48" linestyle="connective"> <pathcodes> <pctext style="entrance" nodeposxrel="1.0" nodeposyrel="-1.0">(Go&space;to&space;next&space;lesson)</pctext> </pathcodes> <pt X="884.1777" Y="833.4691"/> <pt X="886.32825" Y="826.3006"/> </skpath> </sketch> </tunnelxml> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/tutorials/030_lesson_three.xml������������������������������������������������0000644�0000000�0000000�00000010411�12066375447�017126� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-06 16:51:11"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="invisible"> <pt X="735.7561" Y="583.8367"/> <pt X="764.4865" Y="583.8367"/> <pt X="748.63525" Y="586.8088"/> <pt X="746.6538" Y="621.48334"/> <pt X="759.53296" Y="621.48334"/> <pt X="733.7747" Y="621.48334"/> </skpath> <skpath from="2" to="2" linestyle="filled"> <pt X="809.0681" Y="627.42755"/> <pt X="808.0774" Y="579.8738"/> <pt X="836.80774" Y="578.8831"/> <pt X="815.0123" Y="601.66925"/> <pt X="809.0681" Y="627.42755"/> </skpath> <skpath from="3" to="4" linestyle="connective"> <pt X="767.4586" Y="621.48334"/> <pt X="775.3842" Y="581.8552"/> <pt X="786.2819" Y="623.4648"/> <pt X="796.18896" Y="580.86456"/> </skpath> <skpath from="5" to="6" linestyle="detail" splined="1"> <pt X="508.76633" Y="582.72705"/> <pt X="513.71985" Y="615.4202"/> <pt X="525.6083" Y="583.7178"/> <pt X="534.5246" Y="615.4202"/> <pt X="545.4223" Y="575.7921"/> </skpath> <skpath from="7" to="8" linestyle="estwall" splined="1"> <pt X="581.3452" Y="580.7655"/> <pt X="556.5777" Y="580.7655"/> <pt X="553.6056" Y="591.66327"/> <pt X="573.4196" Y="597.6075"/> <pt X="556.5777" Y="601.57025"/> <pt X="552.61487" Y="612.468"/> <pt X="580.35455" Y="615.4401"/> </skpath> <skpath from="9" to="10" linestyle="pitchbound" splined="1"> <pt X="595.07635" Y="615.4202"/> <pt X="595.07635" Y="578.7642"/> <pt X="600.02985" Y="575.7921"/> <pt X="620.8346" Y="576.78284"/> <pt X="623.8067" Y="592.63403"/> <pt X="602.0112" Y="594.6155"/> </skpath> <skpath from="11" to="12" linestyle="ceilingbound" splined="1"> <pt X="664.4057" Y="584.4113"/> <pt X="643.60095" Y="576.48566"/> <pt X="637.65674" Y="588.3741"/> <pt X="635.67535" Y="617.1045"/> <pt X="643.60095" Y="622.058"/> <pt X="662.4243" Y="612.15094"/> </skpath> <skpath from="13" to="14" linestyle="connective"> <pathcodes> <pctext style="entrance" nodeposxrel="-1.0" nodeposyrel="1.0">The&space;seven&space;line&space;types&space;are&space;drawn&space;below:&space;&newline;.&space;Wall&space;.&space;Estimated&space;Wall&space;.&space;&newline;.&space;Pitch&space;Boundary&space;.&space;Ceiling&space;Boundary&space;.&space;&newline;.&space;Detail&space;.&space;Invisible&space;.&space;Connective&space;.&space;&space;Filled&space;.</pctext> </pathcodes> <pt X="510.9775" Y="506.80173"/> <pt X="503.83084" Y="500.36972"/> </skpath> <skpath from="15" to="16" linestyle="detail" splined="1"> <pt X="711.08417" Y="578.2684"/> <pt X="711.08417" Y="620.4337"/> <pt X="709.65485" Y="621.1484"/> <pt X="690.3588" Y="619.0044"/> <pt X="689.64417" Y="602.5671"/> <pt X="708.9402" Y="596.1351"/> </skpath> <skpath from="17" to="18" linestyle="connective"> <pathcodes> <pctext style="entrance" nodeposxrel="-1.0" nodeposyrel="1.0">Click&space;on&space;[Detail&space;Render]&space;to&space;see&space;how&space;they&space;&newline;appear&space;in&space;the&space;final&space;drawing.</pctext> </pathcodes> <pt X="506.40027" Y="631.33295"/> <pt X="511.1171" Y="636.9931"/> </skpath> <skpath from="19" to="20" linestyle="connective"> <pathcodes> <pctext style="entrance" nodeposxrel="-1.0" nodeposyrel="1.0">Select&space;the&space;Wall&space;(W)&space;path&space;&newline;(click&space;on&space;it&space;with&space;the&space;Right-mouse&space;button)&space;&newline;and&space;change&space;its&space;type&space;by&space;using&space;the&space;&newline;drop-down&space;box&space;in&space;the&space;top&space;of&space;the&space;side&space;panel.</pctext> </pathcodes> <pt X="506.87195" Y="671.8974"/> <pt X="504.73782" Y="656.4203"/> </skpath> <skpath from="21" to="22" linestyle="connective"> <pathcodes> <pctext style="passage" nodeposxrel="-1.0" nodeposyrel="1.0">Close&space;this&space;window&space;and&space;&newline;go&space;to&space;the&space;next&space;lesson</pctext> </pathcodes> <pt X="507.8483" Y="752.6639"/> <pt X="511.42163" Y="762.6692"/> </skpath> </sketch> </tunnelxml> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/tutorials/040_joining_nodes.xml�����������������������������������������������0000644�0000000�0000000�00000017234�12066375447�017274� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-06 17:33:51"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="wall" splined="1"> <pt X="730.1634" Y="582.0973"/> <pt X="749.65906" Y="585.87067"/> <pt X="768.5258" Y="585.24176"/> </skpath> <skpath from="2" to="3" linestyle="wall" splined="1"> <pt X="768.5258" Y="584.9273"/> <pt X="777.95917" Y="590.58734"/> <pt X="794.31036" Y="585.5562"/> <pt X="810.6616" Y="588.0718"/> </skpath> <skpath from="4" to="5" linestyle="invisible" splined="1"> <pt X="730.1634" Y="581.78284"/> <pt X="727.3334" Y="600.9641"/> <pt X="731.7356" Y="613.2275"/> </skpath> <skpath from="6" to="7" linestyle="estwall" splined="1"> <pt X="726.07556" Y="609.1397"/> <pt X="740.85455" Y="609.1397"/> <pt X="771.35583" Y="612.5986"/> <pt X="805.9449" Y="618.2586"/> </skpath> <skpath from="8" to="9" linestyle="pitchbound" splined="1"> <pt X="809.08936" Y="621.7175"/> <pt X="812.86273" Y="607.8819"/> <pt X="807.51715" Y="594.3607"/> <pt X="806.88824" Y="583.04065"/> </skpath> <skpath from="10" to="11" linestyle="connective"> <pathcodes> <pctext style="entrance" nodeposxrel="-1.0" nodeposyrel="1.0">None&space;of&space;these&space;paths&newline;are&space;joined</pctext> </pathcodes> <pt X="712.45416" Y="542.6812"/> <pt X="706.7941" Y="547.0835"/> </skpath> <skpath from="12" to="13" linestyle="connective"> <pathcodes> <pctext style="entrance" nodeposxrel="-1.0" nodeposyrel="1.0">These&space;6&space;paths&space;are&space;&newline;joined&space;at&space;5&space;nodes</pctext> </pathcodes> <pt X="541.4145" Y="543.15765"/> <pt X="536.06885" Y="545.0444"/> </skpath> <skpath from="14" to="16" linestyle="wall" splined="1"> <pt X="609.46826" Y="578.1184"/> <pt X="601.6071" Y="577.17505"/> <pt X="587.45703" Y="575.60284"/> <pt X="573.30695" Y="577.17505"/> </skpath> <skpath from="16" to="17" linestyle="invisible" splined="1"> <pt X="573.30695" Y="577.17505"/> <pt X="565.76025" Y="585.6651"/> <pt X="562.6158" Y="595.41296"/> <pt X="559.4713" Y="607.3619"/> </skpath> <skpath from="14" to="15" linestyle="detail" splined="1"> <pt X="609.46826" Y="578.1184"/> <pt X="588.3377" Y="586.8247"/> <pt X="580.8234" Y="597.20215"/> <pt X="598.7771" Y="606.4186"/> </skpath> <skpath from="15" to="17" linestyle="estwall" splined="1"> <pt X="598.7771" Y="606.4186"/> <pt X="578.967" Y="611.13525"/> <pt X="559.4713" Y="607.3619"/> </skpath> <skpath from="18" to="19" linestyle="connective"> <pathcodes> <pctext style="entrance" nodeposxrel="-1.0" nodeposyrel="1.0">You&space;can&space;inspect&space;the&space;junctions&space;by&space;zooming&space;into&space;&newline;them&space;and&space;clicking&space;on&space;the&space;[Stroke&space;<<]&space;button&space;&newline;to&space;change&space;the&space;size&space;of&space;the&space;lines.</pctext> </pathcodes> <pt X="540.53925" Y="626.6378"/> <pt X="546.2565" Y="621.39703"/> </skpath> <skpath from="20" to="21" linestyle="connective"> <pathcodes> <pctext style="entrance" nodeposxrel="-1.0" nodeposyrel="-1.0">Connect&space;these&space;two&space;walls</pctext> </pathcodes> <pt X="541.6676" Y="693.4141"/> <pt X="544.8121" Y="688.383"/> </skpath> <skpath from="22" to="23" linestyle="connective"> <pathcodes> <pctext style="area" nodeposxrel="-1.0" nodeposyrel="0.0">It&space;is&space;very&space;important&space;that&space;paths&space;&newline;join&space;correctly&space;at&space;their&space;end&space;nodes.</pctext> </pathcodes> <pt X="496.49103" Y="507.17017"/> <pt X="489.34436" Y="500.73816"/> </skpath> <skpath from="24" to="25" linestyle="wall" splined="1"> <pt X="553.87506" Y="699.7989"/> <pt X="579.03107" Y="698.70514"/> <pt X="605.2808" Y="695.42395"/> <pt X="632.6243" Y="697.6114"/> <pt X="668.7178" Y="698.70514"/> <pt X="724.49854" Y="697.6114"/> <pt X="763.87317" Y="701.9864"/> <pt X="792.3104" Y="701.9864"/> </skpath> <skpath from="26" to="27" linestyle="wall" splined="1"> <pt X="551.68756" Y="716.205"/> <pt X="575.7499" Y="714.0175"/> <pt X="593.2497" Y="714.0175"/> <pt X="606.3746" Y="714.0175"/> <pt X="619.49945" Y="714.0175"/> </skpath> <skpath from="28" to="29" linestyle="connective"> <pathcodes> <pctext style="entrance" nodeposxrel="0.0" nodeposyrel="1.0" arrowpres="1" boxpres="0">Hold&space;the&space;Control-key&space;&newline;down&space;and&space;Left-mouse&space;&newline;click&space;on&space;this&space;node&space;to&space;&newline;attach&space;the&space;start&space;of&space;&newline;your&space;path&space;here.</pctext> </pathcodes> <pt X="604.1871" Y="744.6423"/> <pt X="618.0369" Y="719.76794"/> </skpath> <skpath from="30" to="31" linestyle="wall" splined="1"> <pt X="734.76306" Y="715.00366"/> <pt X="756.67896" Y="715.9565"/> <pt X="774.307" Y="716.4329"/> <pt X="789.55286" Y="717.3858"/> <pt X="808.1338" Y="715.9565"/> <pt X="814.3274" Y="706.9043"/> <pt X="815.7567" Y="691.18195"/> <pt X="815.7567" Y="679.2711"/> </skpath> <skpath from="31" to="32" linestyle="estwall" splined="1"> <pt X="815.7567" Y="679.2711"/> <pt X="816.23315" Y="659.2609"/> </skpath> <skpath from="32" to="33" linestyle="invisible" splined="1"> <pt X="816.23315" Y="659.2609"/> <pt X="798.12866" Y="659.2609"/> </skpath> <skpath from="33" to="34" linestyle="invisible" splined="1"> <pt X="798.12866" Y="659.2609"/> <pt X="798.12866" Y="677.3654"/> </skpath> <skpath from="34" to="25" linestyle="wall" splined="1"> <pt X="798.12866" Y="677.3654"/> <pt X="798.6051" Y="690.70557"/> <pt X="796.6994" Y="699.75775"/> <pt X="792.3104" Y="701.9864"/> </skpath> <skpath from="31" to="34" linestyle="pitchbound" splined="1"> <pt X="815.7567" Y="679.2711"/> <pt X="811.4688" Y="682.6062"/> <pt X="802.893" Y="681.6533"/> <pt X="798.12866" Y="677.3654"/> </skpath> <skpath from="26" to="24" linestyle="pitchbound" splined="1"> <pt X="551.68756" Y="716.205"/> <pt X="553.87506" Y="699.7989"/> </skpath> <skpath from="35" to="36" linestyle="connective"> <pathcodes> <pctext style="entrance" nodeposxrel="-1.0" nodeposyrel="-1.0">Now&space;close&space;this&space;window&space;and&space;go&space;on&space;to&space;the&space;next&space;lesson</pctext> </pathcodes> <pt X="517.5563" Y="846.1121"/> <pt X="520.0375" Y="848.5933"/> </skpath> <skpath from="37" to="38" linestyle="connective"> <pt X="960.863" Y="860.9993"/> <pt X="951.76526" Y="869.26996"/> </skpath> <skpath from="14" to="39" linestyle="pitchbound" splined="1"> <pt X="609.46826" Y="578.1184"/> <pt X="621.9456" Y="594.24396"/> <pt X="632.996" Y="607.5824"/> </skpath> <skpath from="15" to="39" linestyle="estwall" splined="1"> <pt X="598.7771" Y="606.4186"/> <pt X="610.81635" Y="603.1464"/> <pt X="632.996" Y="607.5824"/> </skpath> <skpath from="40" to="41" linestyle="connective"> <pathcodes> <pctext style="entrance" nodeposxrel="0.0" nodeposyrel="1.0" arrowpres="1" boxpres="0">Hold&space;the&space;Control-key&newline;down&space;again&space;(while&space;you&space;&newline;are&space;drawing)&space;and&space;Left-&newline;mouse&space;click&space;on&space;this&space;&newline;node&space;to&space;attach&space;the&space;end&space;&newline;of&space;your&space;path&space;here.</pctext> </pathcodes> <pt X="774.94543" Y="737.49146"/> <pt X="735.71594" Y="718.8151"/> </skpath> </sketch> </tunnelxml> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/tutorials/060_symbols_areas.xml�����������������������������������������������0000644�0000000�0000000�00000026117�12066375447�017314� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-06 18:15:23"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="connective"> <pt X="960.863" Y="860.9993"/> <pt X="951.76526" Y="869.26996"/> </skpath> <skpath from="2" to="3" linestyle="connective"> <pathcodes> <pctext style="entrance" nodeposxrel="-1.0" nodeposyrel="-1.0">(Go&space;to&space;next&space;lesson)</pctext> </pathcodes> <pt X="762.2916" Y="829.2566"/> <pt X="754.76324" Y="824.65594"/> </skpath> <skpath from="4" to="5" linestyle="connective"> <pathcodes> <pctext style="area" nodeposxrel="-1.0" nodeposyrel="0.0">Symbols&space;in&space;areas</pctext> </pathcodes> <pt X="505.46494" Y="427.88257"/> <pt X="498.49423" Y="447.5273"/> </skpath> <skpath from="6" to="7" linestyle="connective"> <pathcodes> <pctext style="entrance" nodeposxrel="-1.0" nodeposyrel="1.0">Click&space;on&space;the&space;[Update&space;Areas]&space;button.&newline;Then&space;click&space;on&space;the&space;[Update&space;Symbols&space;Lay]&space;button</pctext> </pathcodes> <pt X="521.9412" Y="481.11353"/> <pt X="519.9372" Y="490.9516"/> </skpath> <skpath from="8" to="9" linestyle="detail"> <pt X="705.03436" Y="582.9706"/> <pt X="690.1281" Y="594.5643"/> </skpath> <skpath from="10" to="11" linestyle="connective"> <pathcodes> <pcsymbol rname="puddle"/> </pathcodes> <pt X="614.60876" Y="568.6327"/> <pt X="627.14355" Y="561.9792"/> </skpath> <skpath from="11" to="12" linestyle="wall" splined="1"> <pt X="627.14355" Y="561.9792"/> <pt X="640.8513" Y="563.54236"/> </skpath> <skpath from="13" to="14" linestyle="pitchbound" splined="1"> <pt X="753.61755" Y="576.0695"/> <pt X="761.0707" Y="585.73096"/> <pt X="759.4144" Y="596.4966"/> <pt X="748.3728" Y="607.26215"/> </skpath> <skpath from="11" to="15" linestyle="detail" splined="1"> <pt X="627.14355" Y="561.9792"/> <pt X="627.90106" Y="570.0122"/> <pt X="614.5031" Y="575.3245"/> <pt X="592.7077" Y="576.2607"/> <pt X="581.1297" Y="573.85144"/> <pt X="579.64746" Y="560.65656"/> </skpath> <skpath from="13" to="16" linestyle="connective"> <pathcodes> <pcsymbol rname="boulders"/> </pathcodes> <pt X="753.61755" Y="576.0695"/> <pt X="747.94055" Y="582.158"/> </skpath> <skpath from="15" to="11" linestyle="wall" splined="1"> <pt X="579.64746" Y="560.65656"/> <pt X="584.80414" Y="560.97345"/> <pt X="616.88635" Y="561.8227"/> <pt X="627.14355" Y="561.9792"/> </skpath> <skpath from="17" to="18" linestyle="wall" splined="1"> <pt X="636.38617" Y="588.5117"/> <pt X="632.6214" Y="597.2714"/> <pt X="627.65265" Y="600.5839"/> <pt X="615.2308" Y="603.0683"/> <pt X="606.9496" Y="603.34436"/> </skpath> <skpath from="19" to="14" linestyle="wall" splined="1"> <pt X="698.88684" Y="608.832"/> <pt X="705.03436" Y="609.7465"/> <pt X="724.35724" Y="609.19446"/> <pt X="748.3728" Y="607.26215"/> </skpath> <skpath from="20" to="8" linestyle="detail"> <pt X="701.5507" Y="582.0044"/> <pt X="705.03436" Y="582.9706"/> </skpath> <skpath from="21" to="22" linestyle="detail"> <pt X="699.54663" Y="604.23126"/> <pt X="684.4251" Y="596.7616"/> </skpath> <skpath from="23" to="24" linestyle="connective"> <pathcodes> <pcsymbol rname="slope"/> </pathcodes> <pt X="658.5806" Y="572.3806"/> <pt X="656.3944" Y="579.4859"/> <pt X="662.22437" Y="580.39685"/> </skpath> <skpath from="25" to="26" linestyle="wall" splined="1"> <pt X="622.6839" Y="609.6933"/> <pt X="607.22565" Y="611.0735"/> <pt X="600.3246" Y="611.62555"/> <pt X="593.1475" Y="611.34955"/> </skpath> <skpath from="27" to="23" linestyle="connective"> <pt X="659.5472" Y="567.8671"/> <pt X="658.5806" Y="572.3806"/> </skpath> <skpath from="28" to="29" linestyle="invisible" splined="1"> <pt X="772.7858" Y="576.17444"/> <pt X="773.6968" Y="588.1988"/> <pt X="773.5146" Y="592.5713"/> <pt X="772.42145" Y="599.4944"/> <pt X="770.2352" Y="607.5106"/> </skpath> <skpath from="30" to="31" linestyle="detail"> <pt X="695.3563" Y="585.8303"/> <pt X="695.5385" Y="588.381"/> <pt X="692.25916" Y="588.5632"/> </skpath> <skpath from="32" to="19" linestyle="wall" splined="1"> <pt X="666.5179" Y="598.28485"/> <pt X="677.7063" Y="602.8455"/> <pt X="698.88684" Y="608.832"/> </skpath> <skpath from="12" to="27" linestyle="wall" splined="1"> <pt X="640.8513" Y="563.54236"/> <pt X="649.15344" Y="564.3346"/> <pt X="659.5472" Y="567.8671"/> </skpath> <skpath from="9" to="33" linestyle="detail"> <pt X="690.1281" Y="594.5643"/> <pt X="701.72186" Y="603.67365"/> </skpath> <skpath from="31" to="22" linestyle="detail"> <pt X="692.25916" Y="588.5632"/> <pt X="684.4251" Y="596.7616"/> </skpath> <skpath from="30" to="20" linestyle="detail"> <pt X="695.3563" Y="585.8303"/> <pt X="701.5507" Y="582.0044"/> </skpath> <skpath from="31" to="34" linestyle="detail"> <pt X="692.25916" Y="588.5632"/> <pt X="686.0648" Y="579.8182"/> </skpath> <skpath from="14" to="29" linestyle="estwall" splined="1"> <pt X="748.3728" Y="607.26215"/> <pt X="762.4012" Y="607.3284"/> <pt X="770.2352" Y="607.5106"/> </skpath> <skpath from="35" to="13" linestyle="wall" splined="1"> <pt X="722.4249" Y="575.2414"/> <pt X="732.6384" Y="575.2414"/> <pt X="745.0603" Y="575.51746"/> <pt X="753.61755" Y="576.0695"/> </skpath> <skpath from="36" to="32" linestyle="wall" splined="1"> <pt X="651.25037" Y="593.0049"/> <pt X="666.5179" Y="598.28485"/> </skpath> <skpath from="18" to="25" linestyle="detail" splined="1"> <pt X="606.9496" Y="603.34436"/> <pt X="611.3662" Y="605.2766"/> <pt X="617.71515" Y="606.65686"/> <pt X="622.6839" Y="609.6933"/> </skpath> <skpath from="37" to="38" linestyle="invisible" splined="1"> <pt X="556.88727" Y="560.2627"/> <pt X="553.0851" Y="579.9075"/> </skpath> <skpath from="19" to="21" linestyle="invisible" splined="1"> <pt X="698.88684" Y="608.832"/> <pt X="699.54663" Y="604.23126"/> </skpath> <skpath from="39" to="40" linestyle="wall" splined="1"> <pt X="676.6571" Y="574.20416"/> <pt X="686.26355" Y="573.8612"/> <pt X="695.925" Y="573.8612"/> </skpath> <skpath from="33" to="21" linestyle="detail"> <pt X="701.72186" Y="603.67365"/> <pt X="699.54663" Y="604.23126"/> </skpath> <skpath from="32" to="39" linestyle="pitchbound" splined="1"> <pt X="666.5179" Y="598.28485"/> <pt X="664.61676" Y="590.6804"/> <pt X="665.2505" Y="583.7097"/> <pt X="676.6571" Y="574.20416"/> </skpath> <skpath from="41" to="30" linestyle="detail"> <pt X="687.0917" Y="578.5539"/> <pt X="694.8208" Y="583.52264"/> <pt X="695.3563" Y="585.8303"/> </skpath> <skpath from="17" to="36" linestyle="ceilingbound" splined="1"> <pt X="636.38617" Y="588.5117"/> <pt X="640.9026" Y="591.7506"/> <pt X="651.25037" Y="593.0049"/> </skpath> <skpath from="27" to="39" linestyle="wall" splined="1"> <pt X="659.5472" Y="567.8671"/> <pt X="667.7853" Y="572.30304"/> <pt X="676.6571" Y="574.20416"/> </skpath> <skpath from="13" to="28" linestyle="estwall" splined="1"> <pt X="753.61755" Y="576.0695"/> <pt X="763.4943" Y="575.4457"/> <pt X="772.7858" Y="576.17444"/> </skpath> <skpath from="28" to="42" linestyle="connective"> <pathcodes> <pcsymbol rname="stream"/> </pathcodes> <pt X="772.7858" Y="576.17444"/> <pt X="767.8155" Y="587.67883"/> <pt X="758.15405" Y="590.4392"/> </skpath> <skpath from="40" to="35" linestyle="estwall" splined="1"> <pt X="695.925" Y="573.8612"/> <pt X="686.5396" Y="562.5435"/> <pt X="693.4406" Y="548.1894"/> <pt X="711.3833" Y="543.4967"/> <pt X="729.602" Y="549.0175"/> <pt X="732.08636" Y="560.61127"/> <pt X="724.0812" Y="573.30914"/> <pt X="722.4249" Y="575.2414"/> </skpath> <skpath from="25" to="43" linestyle="connective"> <pathcodes> <pcsymbol rname="bedrock"/> </pathcodes> <pt X="622.6839" Y="609.6933"/> <pt X="628.98047" Y="603.6072"/> </skpath> <skpath from="33" to="44" linestyle="detail"> <pt X="701.72186" Y="603.67365"/> <pt X="716.35205" Y="594.84033"/> </skpath> <skpath from="34" to="41" linestyle="detail"> <pt X="686.0648" Y="579.8182"/> <pt X="687.0917" Y="578.5539"/> </skpath> <skpath from="35" to="40" linestyle="pitchbound" splined="1"> <pt X="722.4249" Y="575.2414"/> <pt X="711.2066" Y="577.44977"/> <pt X="701.7329" Y="576.5388"/> <pt X="695.925" Y="573.8612"/> </skpath> <skpath from="8" to="44" linestyle="detail"> <pt X="705.03436" Y="582.9706"/> <pt X="716.35205" Y="594.84033"/> </skpath> <skpath from="23" to="45" linestyle="connective"> <pathcodes> <pcsymbol rname="slope"/> </pathcodes> <pt X="658.5806" Y="572.3806"/> <pt X="664.95715" Y="575.4778"/> </skpath> <skpath from="37" to="15" linestyle="wall" splined="1"> <pt X="556.88727" Y="560.2627"/> <pt X="579.64746" Y="560.65656"/> </skpath> <skpath from="22" to="9" linestyle="detail"> <pt X="684.4251" Y="596.7616"/> <pt X="690.1281" Y="594.5643"/> </skpath> <skpath from="36" to="25" linestyle="wall" splined="1"> <pt X="651.25037" Y="593.0049"/> <pt X="646.8399" Y="599.46924"/> <pt X="638.10754" Y="605.77576"/> <pt X="622.6839" Y="609.6933"/> </skpath> <skpath from="46" to="47" linestyle="connective"> <pathcodes> <pctext style="entrance" nodeposxrel="-1.0" nodeposyrel="1.0">Symbols&space;in&space;areas&newline;&newline;Islands&space;in&space;areas&space;invisible&space;lines.&newline;&newline;Pitch&space;holes.</pctext> </pathcodes> <pt X="529.6801" Y="646.7482"/> <pt X="532.1921" Y="658.30316"/> </skpath> <skpath from="38" to="48" linestyle="wall" splined="1"> <pt X="553.0851" Y="579.9075"/> <pt X="574.0802" Y="581.27527"/> </skpath> <skpath from="49" to="17" linestyle="wall" splined="1"> <pt X="578.4068" Y="581.5336"/> <pt X="584.13654" Y="581.8086"/> <pt X="610.752" Y="582.4423"/> <pt X="636.38617" Y="588.5117"/> </skpath> <skpath from="49" to="18" linestyle="wall" splined="1"> <pt X="578.4068" Y="581.5336"/> <pt X="578.70734" Y="586.09955"/> <pt X="583.7625" Y="593.1769"/> <pt X="590.6954" Y="598.6654"/> <pt X="598.0616" Y="601.98737"/> <pt X="606.9496" Y="603.34436"/> </skpath> <skpath from="18" to="50" linestyle="connective"> <pathcodes> <pcarea area_signal="rock"/> </pathcodes> <pt X="606.9496" Y="603.34436"/> <pt X="609.61633" Y="595.92114"/> </skpath> <skpath from="26" to="48" linestyle="wall" splined="1"> <pt X="593.1475" Y="611.34955"/> <pt X="589.25104" Y="610.3646"/> <pt X="585.06244" Y="607.4759"/> <pt X="585.4957" Y="602.13184"/> <pt X="582.75146" Y="597.79877"/> <pt X="577.8407" Y="593.61017"/> <pt X="575.5297" Y="590.14374"/> <pt X="574.66315" Y="586.53284"/> <pt X="574.0802" Y="581.27527"/> </skpath> </sketch> </tunnelxml> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/t.bat�������������������������������������������������������������������������0000644�0000000�0000000�00000000362�12261213471�012222� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������REM get the name of the file right for the release tar --create --gzip --file=tunnel2012-12.tar.gz --transform='s:^:tunnel2012-12/:' src symbols tutorials b.bat j.bat REM then add this to https://bitbucket.org/goatchurch/tunnelx/downloads ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/AATunnelTopParser.java��������������������������������������������������������0000644�0000000�0000000�00000013426�11762432750�015456� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//////////////////////////////////////////////////////////////////////////////// // TunnelX -- Cave Drawing Program // Copyright (C) 2011 Julian Todd. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // FoUndation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// // See TopParser/readtop.py for the source code import java.awt.geom.Line2D; import java.awt.geom.GeneralPath; import java.util.List; import java.util.ArrayList; import java.awt.Font; import java.awt.Color; import java.awt.geom.AffineTransform; import java.io.IOException; import java.io.BufferedReader; import java.io.InputStream; import java.io.Reader; import java.io.File; import java.io.FileInputStream; import java.io.StringReader; import java.io.FileReader; import java.io.StreamTokenizer; import java.io.InputStreamReader; ///////////////////////////////////////////// class TN { static void emitWarning(String s) { System.out.println(s); } } ///////////////////////////////////////////// // placeholder class (add more parameters as necessary) which we can use to hold the data // before it gets imported into other systems (eg tunnel) class OnePath { String stationfrom = ""; String stationto = ""; GeneralPath gp = null; OnePath() { } }; ///////////////////////////////////////////// class AATunnelTopParser { List<OnePath> paths = new ArrayList<OnePath>(); int version; ///////////////////////////////////////////// int ReadInt(InputStream inp) throws IOException { int b0 = inp.read(); int b1 = inp.read(); int b2 = inp.read(); int b3 = inp.read(); int res = b0 + (b1 << 8) + (b2 << 16) + (b3 << 24); System.out.println("eee "+b0+" "+b1+" "+b2+" "+b3+" "+res); return res; } ///////////////////////////////////////////// int ReadDate(InputStream inp) throws IOException { byte[] sdate = new byte[8]; inp.read(sdate, 0, 8); System.out.println(ReadInt(inp)+" "+ReadInt(inp)); return 0; // ticks = struct.unpack('<Q', F.read(8)) // #Need to convert this date from .NET // NANOSEC = 10000000 // #Number of python tick since 1/1/1 00:00 // PTICKS = 62135596800 // tripdate = time.gmtime((ticks[0]/NANOSEC)-PTICKS) } ///////////////////////////////////////////// String ReadComments(InputStream inp) throws IOException { int commentlength = inp.read(); if (commentlength >= 128) { int commentlength2 = inp.read(); commentlength = commentlength - 128 + 128*commentlength2; assert commentlength2 < 128; } System.out.println("Commentlength "+commentlength); byte[] cstr = new byte[commentlength]; return new String(cstr); } ///////////////////////////////////////////// boolean ParseFile(File tfile) { try { InputStream inp = new FileInputStream(tfile); byte[] htop = new byte[3]; inp.read(htop, 0, 3); System.out.println(new String(htop)); assert "Top".equals(new String(htop)); version = inp.read(); TN.emitWarning("We have a top file version " + version); int ntrips = ReadInt(inp); for (int i = 0; i < ntrips; i++) { ReadDate(inp); String comments = ReadComments(inp); System.out.println("::"+comments+"::"); int declination = (inp.read()<<8) + inp.read(); System.out.println("declination "+declination); } for (int i = 0; i < 10; i++) System.out.println(i+" "+inp.read()); inp.close(); } catch (IOException e) { TN.emitWarning(e.toString()); } return false; } ///////////////////////////////////////////// // startup the program public static void main(String args[]) { if (args.length != 0) { AATunnelTopParser aatunneltopparser = new AATunnelTopParser(); aatunneltopparser.ParseFile(new File(args[0])); System.out.println("We have read "+aatunneltopparser.paths.size()+" paths"); } else TN.emitWarning("need to put in a file name"); } } /* def station(F): #id's split into major.decimal(minor) idd = struct.unpack('<H', F.read(2)) idm = struct.unpack('<H', F.read(2)) #Turn stn into string, andnulls into - if idm[0] == 32768: stnid = "-" else: stnid = str(idm[0])+"."+str(idd[0]) return stnid def shot(F): thline = {'from' : station(F)} thline['to'] = station(F) Dist = struct.unpack('<L', F.read(4)) thline['tape'] = distmm(Dist[0]) azimuth = struct.unpack('<H', F.read(2)) thline['compass'] = adegrees(azimuth[0]) inclination = struct.unpack('<h', F.read(2)) thline['clino'] = adegrees(inclination[0]) flags = struct.unpack('<B', F.read(1)) #Roll of the DistoX on taking reading can be ignored #Internal angle interger 0-256 #Roll = struct.unpack('<B', F.read(1)) F.read(1) tripindex = struct.unpack('<h', F.read(2)) thline['trip'] = tripindex[0] #bit 1 of flags is flip (left or right) #bit 2 of flags indicates a comment if (flags[0] & 0b00000001) == 0b000000001: thline['direction'] = '<' else: thline['direction'] = '>' if (flags[0] & 0b00000010) == 0b000000010: thline['comment'] = comments(F) return thline */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/tunnelmanifest.txt������������������������������������������������������������0000644�0000000�0000000�00000000035�11762432750�015071� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Main-Class: Tunnel.MainBox ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/rerw.bat����������������������������������������������������������������������0000644�0000000�0000000�00000000155�11762432750�012746� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������java -showversion -ea -Xmx400M -cp . Tunnel.MainBox C:\tunnel\houping\Survey_data\sketches\48h-h12-2-erwang �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/build�������������������������������������������������������������������������0000755�0000000�0000000�00000001222�11762432750�012320� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/bash echo "Compiling" rm Tunnel/*.class export CLASSPATH=.:j3dcore.jar:j3dutils.jar:vecmath.jar #export LD_LIBRARY_PATH=/home/goatchurch/expo/tunnelx/j3dlib/i386 javac -target 1.5 -version -d . src/*.java echo "Buiding jar file" ls -w1 symbols > symbols\listdir.txt jar cmf tunnelmanifest.txt tunnel.jar Tunnel symbols/*.xml symbols/listdir.txt symbols/helpfile.html #jar tf tunnel.jar echo "Backing up src" zip -q tunnelsrc src/*java echo "Copying to mmmmc" cp tunnel.jar ../mmmmc/tunnelprogram/ cp symbols/*.xml ../mmmmc/tunnelprogram/symbols/ #cp symbols/helpfile.html ../mmmmc/tunnelprogram/symbols/ mv tunnelsrc.zip ../mmmmc/tunnelprogram/ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/runtunnel.bat�����������������������������������������������������������������0000644�0000000�0000000�00000000064�12066375446�014026� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������java -showversion -ea -Xmx2000M -cp . Tunnel.MainBox����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/bw.bat������������������������������������������������������������������������0000644�0000000�0000000�00000000412�11762432750�012373� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������"C:\Program Files\Java\jdk1.6.0\bin\javac" -d . src\*.java dir/b symbols > symbols\listdir.txt "C:\Program Files\Java\jdk1.6.0\bin\jar" cmf tunnelmanifest.txt tunnel.jar Tunnel symbols/*.xml symbols/listdir.txt "C:\Program Files\Java\jdk1.6.0\bin\jar" i tunnel.jar ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/r�����������������������������������������������������������������������������0000755�0000000�0000000�00000000232�12261213471�011452� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������java -showversion -ea -Xmx2000M -cp . Tunnel.MainBox /media/data/Andrew/Caving/CUCC_Expoweb/expoimages/surveyscans/2010/2010#20/StraightChoiceExposed.top ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/r.bat�������������������������������������������������������������������������0000755�0000000�0000000�00000003031�12261213471�012217� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������java -showversion -ea -Xmx2000M -cp . Tunnel.MainBox C:\\Users\\goatchurch\\caving\\YorkshireSVN\\mmmmc\\tunneldata REM java -showversion -ea -Xmx2000M -cp . Tunnel.MainBox C:\\Users\\goatchurch\\caving\\YorkshireSVN\\mmmmc\\rawscans\\GetDownShep\\getdownshep.top REM java -showversion -ea -Xmx1000M -cp . Tunnel.MainBox C:\\Users\\goatchurch\\tunneldata REM java -showversion -ea -Xmx1000M -cp . Tunnel.MainBox http://seagrass.goatchurch.org.uk/~expo/tunneldata/ REM java -showversion -ea -Xmx1000M -cp . Tunnel.MainBox C:\\Users\\goatchurch\\tunneldata\\204-piece-frame-side.xml REM java -showversion -ea -Xmx2000M -cp . Tunnel.MainBox C:\\Users\\goatchurch\\caving\\tunneldata REM java -showversion -ea -Xmx2000M -cp . Tunnel.MainBox "C:\\Users\\goatchurch\\caving\\expoimages\\surveyscans\\2010\\2010#20" REM java -showversion -ea -Xmx2000M -cp . Tunnel.MainBox C:\\Users\\goatchurch\\caving\\expoimages\\surveyscans\\2010\\2010#20\\StraightChoiceExposed.top REM java -showversion -ea -Xmx2000M -cp . Tunnel.MainBox C:\\Users\\goatchurch\\caving\\tunneldata\\161\\dddphumour2.xml REM java -showversion -ea -Xmx2000M -cp . Tunnel.MainBox C:\\Users\\goatchurch\\caving\\YorkshireSVN\\mmmmc\\tunneldata REM -- should work when no survex installed by uploading to executable on server REM -- allow net upload to take path, save on server and commit to mercurial (with username) REM -- release of jar file which downloads the current conditions from the net and configures itself REM -- automatic tail uploading of any edits as they happen �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/����������������������������������������������������������������������0000755�0000000�0000000�00000000000�12261213471�012756� 5����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/bigboulder1.xml�������������������������������������������������������0000755�0000000�0000000�00000002462�12066375447�015725� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:08"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="centreline"> <pt X="2104.5764" Y="-315.32117"/> <pt X="2124.5808" Y="-335.06223"/> </skpath> <skpath from="2" to="2" linestyle="detail"> <pt X="2109.2732" Y="-334.1788"/> <pt X="2104.686" Y="-315.56024"/> <pt X="2125.9128" Y="-315.74014"/> <pt X="2125.1033" Y="-335.88776"/> <pt X="2109.2732" Y="-334.1788"/> </skpath> <skpath from="3" to="3" linestyle="invisible"> <pt X="2107.654" Y="-336.1576"/> <pt X="2103.3367" Y="-315.11053"/> <pt X="2104.8657" Y="-313.94125"/> <pt X="2125.2832" Y="-313.49152"/> <pt X="2127.8018" Y="-315.83008"/> <pt X="2127.082" Y="-334.3587"/> <pt X="2124.5637" Y="-337.32687"/> <pt X="2107.654" Y="-336.1576"/> </skpath> <skpath from="0" to="2" linestyle="invisible"> <pt X="2104.5764" Y="-315.32117"/> <pt X="2109.2732" Y="-334.1788"/> </skpath> <skpath from="3" to="2" linestyle="invisible" splined="1"> <pt X="2107.654" Y="-336.1576"/> <pt X="2109.2732" Y="-334.1788"/> </skpath> </sketch> </tunnelxml> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/helictite.xml���������������������������������������������������������0000644�0000000�0000000�00000003036�12066375447�015473� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:09"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="centreline" splined="1"> <pt X="29.293903" Y="-179.17351"/> <pt X="30.866232" Y="-179.17351"/> </skpath> <skpath from="2" to="3" linestyle="detail"> <pt X="30.0" Y="-180.0"/> <pt X="27.999245" Y="-180.01166"/> <pt X="27.999245" Y="-183.29419"/> </skpath> <skpath from="4" to="5" linestyle="detail"> <pt X="30.0" Y="-180.0"/> <pt X="29.984644" Y="-183.26772"/> </skpath> <skpath from="2" to="6" linestyle="detail"> <pt X="30.0" Y="-180.0"/> <pt X="29.984644" Y="-176.46442"/> </skpath> <skpath from="4" to="7" linestyle="detail"> <pt X="30.0" Y="-180.0"/> <pt X="31.890627" Y="-180.01166"/> <pt X="31.890627" Y="-176.43794"/> </skpath> <skpath from="3" to="8" linestyle="invisible"> <pt X="27.999245" Y="-183.29419"/> <pt X="27.2845" Y="-184.00893"/> </skpath> <skpath from="8" to="8" linestyle="invisible"> <pt X="27.2845" Y="-184.00893"/> <pt X="30.911163" Y="-184.00893"/> <pt X="30.911163" Y="-180.75287"/> <pt X="32.737732" Y="-180.75287"/> <pt X="32.737732" Y="-175.64378"/> <pt X="29.058125" Y="-175.64378"/> <pt X="29.058125" Y="-179.13808"/> <pt X="27.310972" Y="-179.13808"/> <pt X="27.2845" Y="-184.00893"/> </skpath> </sketch> </tunnelxml> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/breeze.xml������������������������������������������������������������0000755�0000000�0000000�00000003707�12066375447�015005� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:08"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="centreline"> <pt X="20.0" Y="-165.0"/> <pt X="40.0" Y="-165.0"/> </skpath> <skpath from="1" to="2" linestyle="detail" splined="1"> <pt X="40.0" Y="-165.0"/> <pt X="35.0" Y="-165.0"/> </skpath> <skpath from="3" to="0" linestyle="detail" splined="1"> <pt X="25.0" Y="-170.0"/> <pt X="20.0" Y="-165.0"/> </skpath> <skpath from="4" to="0" linestyle="detail" splined="1"> <pt X="25.0" Y="-160.0"/> <pt X="20.0" Y="-165.0"/> </skpath> <skpath from="5" to="1" linestyle="detail" splined="1"> <pt X="45.0" Y="-170.0"/> <pt X="40.0" Y="-165.0"/> </skpath> <skpath from="6" to="1" linestyle="detail" splined="1"> <pt X="45.0" Y="-160.0"/> <pt X="40.0" Y="-165.0"/> </skpath> <skpath from="2" to="0" linestyle="detail" splined="1"> <pt X="35.0" Y="-165.0"/> <pt X="20.0" Y="-165.0"/> </skpath> <skpath from="2" to="7" linestyle="detail" splined="1"> <pt X="35.0" Y="-165.0"/> <pt X="40.0" Y="-160.0"/> </skpath> <skpath from="2" to="8" linestyle="detail" splined="1"> <pt X="35.0" Y="-165.0"/> <pt X="40.0" Y="-170.0"/> </skpath> <skpath from="9" to="9" linestyle="invisible"> <pt X="17.845297" Y="-165.16876"/> <pt X="22.576473" Y="-158.12233"/> <pt X="47.742294" Y="-158.12233"/> <pt X="47.440304" Y="-161.14223"/> <pt X="44.118416" Y="-164.86678"/> <pt X="47.641632" Y="-169.09464"/> <pt X="47.54097" Y="-171.81255"/> <pt X="21.368513" Y="-172.2152"/> <pt X="17.845297" Y="-165.16876"/> </skpath> <skpath from="0" to="9" linestyle="invisible" splined="1"> <pt X="20.0" Y="-165.0"/> <pt X="17.845297" Y="-165.16876"/> </skpath> </sketch> </tunnelxml> ���������������������������������������������������������tunnelx-20140102.orig/symbols/stalactite.xml��������������������������������������������������������0000644�0000000�0000000�00000003066�12066375447�015661� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:09"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="centreline" splined="1"> <pt X="30.0" Y="-180.0"/> <pt X="30.0" Y="-180.0"/> </skpath> <skpath from="2" to="0" linestyle="detail"> <pt X="27.131954" Y="-182.90779"/> <pt X="30.0" Y="-180.0"/> </skpath> <skpath from="3" to="0" linestyle="detail"> <pt X="32.585964" Y="-182.66211"/> <pt X="30.0" Y="-180.0"/> </skpath> <skpath from="4" to="0" linestyle="detail" splined="1"> <pt X="30.0" Y="-175.0"/> <pt X="30.0" Y="-180.0"/> </skpath> <skpath from="5" to="6" linestyle="centreline" splined="1"> <pt X="29.293903" Y="-179.17351"/> <pt X="30.866232" Y="-179.17351"/> </skpath> <skpath from="7" to="7" linestyle="invisible"> <pt X="26.675919" Y="-183.27391"/> <pt X="26.314766" Y="-182.98047"/> <pt X="29.091124" Y="-179.79782"/> <pt X="29.226555" Y="-174.58368"/> <pt X="30.603447" Y="-174.51596"/> <pt X="30.85174" Y="-179.63982"/> <pt X="33.515236" Y="-182.50645"/> <pt X="32.612354" Y="-183.38676"/> <pt X="29.903715" Y="-181.265"/> <pt X="27.37565" Y="-183.74792"/> <pt X="26.675919" Y="-183.27391"/> </skpath> <skpath from="2" to="7" linestyle="invisible" splined="1"> <pt X="27.131954" Y="-182.90779"/> <pt X="26.675919" Y="-183.27391"/> </skpath> </sketch> </tunnelxml> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/stalagtite.xml��������������������������������������������������������0000644�0000000�0000000�00000003066�12066375447�015665� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:09"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="centreline" splined="1"> <pt X="30.0" Y="-180.0"/> <pt X="30.0" Y="-180.0"/> </skpath> <skpath from="2" to="0" linestyle="detail"> <pt X="27.131954" Y="-182.90779"/> <pt X="30.0" Y="-180.0"/> </skpath> <skpath from="3" to="0" linestyle="detail"> <pt X="32.585964" Y="-182.66211"/> <pt X="30.0" Y="-180.0"/> </skpath> <skpath from="4" to="0" linestyle="detail" splined="1"> <pt X="30.0" Y="-175.0"/> <pt X="30.0" Y="-180.0"/> </skpath> <skpath from="5" to="6" linestyle="centreline" splined="1"> <pt X="29.293903" Y="-179.17351"/> <pt X="30.866232" Y="-179.17351"/> </skpath> <skpath from="7" to="7" linestyle="invisible"> <pt X="26.675919" Y="-183.27391"/> <pt X="26.314766" Y="-182.98047"/> <pt X="29.091124" Y="-179.79782"/> <pt X="29.226555" Y="-174.58368"/> <pt X="30.603447" Y="-174.51596"/> <pt X="30.85174" Y="-179.63982"/> <pt X="33.515236" Y="-182.50645"/> <pt X="32.612354" Y="-183.38676"/> <pt X="29.903715" Y="-181.265"/> <pt X="27.37565" Y="-183.74792"/> <pt X="26.675919" Y="-183.27391"/> </skpath> <skpath from="2" to="7" linestyle="invisible" splined="1"> <pt X="27.131954" Y="-182.90779"/> <pt X="26.675919" Y="-183.27391"/> </skpath> </sketch> </tunnelxml> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/sump.xml��������������������������������������������������������������0000755�0000000�0000000�00000003230�12066375447�014504� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:09"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="detail"> <pt X="-80.0" Y="-25.0"/> <pt X="-82.5" Y="-22.5"/> </skpath> <skpath from="2" to="3" linestyle="centreline"> <pt X="-82.5" Y="-20.0"/> <pt X="-82.5" Y="-25.0"/> </skpath> <skpath from="0" to="3" linestyle="invisible"> <pt X="-80.0" Y="-25.0"/> <pt X="-82.5" Y="-25.0"/> </skpath> <skpath from="4" to="2" linestyle="invisible" splined="1"> <pt X="-85.0" Y="-20.0"/> <pt X="-82.5" Y="-20.0"/> </skpath> <skpath from="4" to="5" linestyle="invisible" splined="1"> <pt X="-85.0" Y="-20.0"/> <pt X="-85.0" Y="-25.0"/> </skpath> <skpath from="3" to="5" linestyle="invisible" splined="1"> <pt X="-82.5" Y="-25.0"/> <pt X="-85.0" Y="-25.0"/> </skpath> <skpath from="2" to="6" linestyle="invisible" splined="1"> <pt X="-82.5" Y="-20.0"/> <pt X="-80.0" Y="-20.0"/> </skpath> <skpath from="0" to="6" linestyle="invisible" splined="1"> <pt X="-80.0" Y="-25.0"/> <pt X="-80.0" Y="-20.0"/> </skpath> <skpath from="1" to="4" linestyle="detail"> <pt X="-82.5" Y="-22.5"/> <pt X="-85.0" Y="-20.0"/> </skpath> <skpath from="5" to="1" linestyle="detail" splined="1"> <pt X="-85.0" Y="-25.0"/> <pt X="-82.5" Y="-22.5"/> </skpath> <skpath from="6" to="1" linestyle="detail" splined="1"> <pt X="-80.0" Y="-20.0"/> <pt X="-82.5" Y="-22.5"/> </skpath> </sketch> </tunnelxml> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/stalagmite.xml��������������������������������������������������������0000755�0000000�0000000�00000005147�12066375447�015663� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:09"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="centreline" splined="1"> <pt X="29.293903" Y="-179.17351"/> <pt X="30.866232" Y="-179.17351"/> </skpath> <skpath from="2" to="3" linestyle="detail" splined="1"> <pt X="29.941442" Y="-183.15138"/> <pt X="29.988285" Y="-175.7501"/> </skpath> <skpath from="4" to="3" linestyle="detail"> <pt X="32.564682" Y="-173.1737"/> <pt X="29.988285" Y="-175.7501"/> </skpath> <skpath from="5" to="3" linestyle="detail"> <pt X="27.365047" Y="-173.12686"/> <pt X="29.988285" Y="-175.7501"/> </skpath> <skpath from="2" to="6" linestyle="invisible" splined="1"> <pt X="29.941442" Y="-183.15138"/> <pt X="29.929035" Y="-184.55003"/> </skpath> <skpath from="6" to="7" linestyle="invisible" splined="1"> <pt X="29.929035" Y="-184.55003"/> <pt X="28.958012" Y="-184.03595"/> <pt X="28.815214" Y="-183.1506"/> </skpath> <skpath from="6" to="8" linestyle="invisible" splined="1"> <pt X="29.929035" Y="-184.55003"/> <pt X="30.928617" Y="-184.15019"/> <pt X="31.042856" Y="-183.12206"/> </skpath> <skpath from="7" to="9" linestyle="invisible" splined="1"> <pt X="28.815214" Y="-183.1506"/> <pt X="28.929453" Y="-176.23921"/> </skpath> <skpath from="9" to="10" linestyle="invisible" splined="1"> <pt X="28.929453" Y="-176.23921"/> <pt X="26.673252" Y="-173.84021"/> </skpath> <skpath from="11" to="12" linestyle="invisible" splined="1"> <pt X="27.929869" Y="-172.52647"/> <pt X="29.986155" Y="-174.75412"/> </skpath> <skpath from="12" to="13" linestyle="invisible" splined="1"> <pt X="29.986155" Y="-174.75412"/> <pt X="31.985321" Y="-172.64072"/> </skpath> <skpath from="8" to="14" linestyle="invisible" splined="1"> <pt X="31.042856" Y="-183.12206"/> <pt X="30.985737" Y="-176.41057"/> </skpath> <skpath from="14" to="15" linestyle="invisible" splined="1"> <pt X="30.985737" Y="-176.41057"/> <pt X="33.15626" Y="-174.01157"/> </skpath> <skpath from="10" to="11" linestyle="invisible" splined="1"> <pt X="26.673252" Y="-173.84021"/> <pt X="26.387655" Y="-172.298"/> <pt X="27.929869" Y="-172.52647"/> </skpath> <skpath from="15" to="13" linestyle="invisible" splined="1"> <pt X="33.15626" Y="-174.01157"/> <pt X="33.584652" Y="-172.38368"/> <pt X="31.985321" Y="-172.64072"/> </skpath> </sketch> </tunnelxml> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/boulder.xml�����������������������������������������������������������0000755�0000000�0000000�00000001417�12066375447�015161� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:08"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="detail"> <pt X="2109.4937" Y="-324.88602"/> <pt X="2115.9255" Y="-328.9881"/> <pt X="2120.723" Y="-325.04794"/> </skpath> <skpath from="1" to="0" linestyle="detail"> <pt X="2120.723" Y="-325.04794"/> <pt X="2114.9312" Y="-320.11725"/> <pt X="2109.4937" Y="-324.88602"/> </skpath> <skpath from="2" to="3" linestyle="centreline"> <pt X="2103.084" Y="-325.6024"/> <pt X="2115.2346" Y="-324.84296"/> </skpath> </sketch> </tunnelxml> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/helpfile.html���������������������������������������������������������0000644�0000000�0000000�00000054057�12261213471�015447� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1>Drawing</h1> <p>Click the <b>Left Mouse Button</b> in the graphics pane whilst (optionally) holding down the <em>Shift</em> or <em>Control</em> keys.</p> <ul> <li><b>Shift</b> + <b>Left Mouse</b> ends a path</li> <li><b>Control</b> + <b>Left Mouse</b> starts or ends on a node</li> <li><b>Shift+Control</b> + <b>Left Mouse</b> inserts a node on a selected path</li> </ul> <p>The drop-down box in the top left of the window (or single letter buttons <tt>'W' 'E' 'P' 'C' 'D' 'I' 'N' 'F'</tt>) sets the type of the selected path, with <tt><b>'S'</b></tt> controlling the spline. Buttons:</p> <ul> <li><b>Delete</b> acts on any number of selected paths</li> <li><b>Back</b> undo last click or button</li> <li><b>Reflect</b> reverses direction of the selected path</li> <li><b>Fuse</b> joins two selected paths</li> </ul> <p>The <b>img</b> tab has a <b>Snap to grid</b> feature where you can change the grid spacing.</p> <p>Centreline paths cannot be deleted without setting the menu <b>Action</b> -> <b>Allow Delete Centreline</b>.</p> <p>The <em>Pitch Bound</em> and <em>Ceiling Bound</em> paths have a dash on one side to show the direction of the 'whiskers' (always to the right according to the direction it was drawn). Click <b>Reflect</b> to reverse it.</p> <p>Connecting to the correct node among an overlapping set (some will be drawn as diamonds and pentagons) is possible by dragging away from the <em>Control+Left Mouse</em> selected node without releasing it in order to select the next one.</p> <h1>Viewing</h1> <p>Click and drag with the <b>Middle Mouse Button</b> to move the viewing position. Zoom with the <b>Scroll-wheel</b> or by holding the <b>Control-key</b> down before you click and drag the middle mouse.</p> <p>The <b>View</b> menu contains the <b>Max</b> feature, and <b>Display</b> can turn on station names. Change the thickness of the lines using the <b>Stroke</b> buttons. Draw the final result with <b>Detail render</b>.</p> <p>The <b>view</b> tab shows a second pane where you can store the current view using the <b>Copy</b> button.</p> <h1>Selecting</h1> <p>Click the <b>Right Mouse Button</b> on the desired path whilst (optionally) holding down the <em>Shift</em> or <em>Control</em> keys. Multiple clicks cycle through the overlapping paths.</p> <ul> <li><b>Control</b> + <b>Right Mouse</b> selects (or deselects) multiple paths</li> <li><b>Shift</b> + <b>Right Mouse</b> selects all paths for an area</li> </ul> <p>The <b>Component</b> button selects all paths that connect to the selected path(s). Click <b>Component</b> again to select all paths to one side of the selected path(s).</p> <p>Fuse and fuse translate</p> <h1>Centreline</h1> <p>TunnelX is <em>Survex</em> based. (see http://www.survex.com) Either use <b>Import</b> -> <b>Import survex file</b> to load the centreline data, or do <b>File</b> -> <b>Open survex...</b> from the Main window. The centreline data can be previewed by selecting the dotted green (connective) 'S' to see the label text, or do <b>Import</b> -> <b>Wireframe view</b> to see the centreline in <em>Survex-Aven<em>.</p> <p>If <em>Survex</em> is not found, <b>Import</b> -> <b>Use Survex</b> should be disabled, and TunnelX's computation (without loop closures) will be used.</p> <p>Do <b>Import</b> -> <b>Import centreline</b> to load the geometry defined by the <em>Survex</em> data.</p> <p>You can import a centreline as an elevation by including the line:<br /> ;IMPORT_AS_ELEVATION 60<br /> somewhere in the survex file (where 60 is the angle of projection). All this does is loads it through a transformation which swaps the y axis for the z axis. </p> <h1>Backgrounds</h1> <p>Select the <b>img</b> tab for loading and moving the background image. <b>Add image</b> adds a new image to the background.</p> <p><b>Select image</b> requires the rectangle outline of an image to be selected. Alternatively, use the drop-down box of visible background images.</p> <p>Move the selected image into position by drawing a single line path and clicking on the <b>Shift ground</b> button. Rotate and resize the image by drawing a three point (two line) path before clicking <b>Shift ground</b> -- the first point is the centre of rotation while the second point is moved to the third point.</p> <p>Always connect the corner of the rectangle outline of the image to part of the passage it depicts so that it stays in place when the passage moves.</p> <p><em>Not done yet:</em> It will be possible to draw smaller areas to trim out from the big rectangular paper to show only what is required and to make it possible to render multiple background images without too much undesirtable overlapping. This may also be used to bring together scattered cross-sectional outlines.</p> <h1>Files</h1> <p>The Main window show the list of sketch files. Double-click (or select it and do <b>Tunnel</b> -> <b>View sketch</b>) to work on the drawing. Open a new file using <b>File</b> -> <b>Open sketch...</b>.</p> <p>The file name is <em>green</em> when it is loaded and up to date, and <em>red</em> if it needs to be saved.</p> From the drawing window, use <b>File</b> -> <b>Save as...</b> to give it a different name.</p> <p>To copy another sketch into the current sketch (while distorting to fit the centreline), select it in the Main window and do <b>Import</b> -> <b>Import down sketch</b>. Always preview the import using <b>Preview down sketch</b>.</p> <p>Sketches can be downloaded from the internet by pasting their 'http://...' url into the file open dialog.</p> <h1>Areas</h1> <p>The <b>Update areas</b> button creates the areas of the sketch by finding the closed outlines of series of paths that are properly joined up at their nodes. Paths of type <em>Centreline</em> and <em>Connective</em> are ignored, but <em>Invisible</em> paths count. Preview the areas with <b>Display</b> -> <b>Stripe areas</b>. If areas do not appear, check for failed joins or unintended crossings near nodes, and that the area itself does not self-intersect.</p> <p>Disconnected features or rock pillars within an area must be joined with an <em>Invisible</em> path. The filling in of a rock pillar is disabled by drawing a <em>Connective</em> path into it from one of the nodes, clicking <b>Area signal</b> and selecting <em>rock</em> from the drop-down box. Then do <b>Update areas</b> to refresh.</p> <h1>Z-depth</h1> <p>The altitude of the paths and nodes are defined by the average of the nearest three centreline stations (by connectivity). Compute this by clicking the <b>Update Node Z</b> button. The areas will be sorted by their average altitude and rendered in order.</p> <p>Paths (and their areas) can be forced to a relative altitude by connecting them by a <em>Connective</em> line to a centreline node, clicking <b>Area signal</b>, selecting <em>zsetrelative</em> and changing the <tt>0.0</tt> to a different displacement.</p> <p>Select a <em>Pitch Boundary</em> type path and do <b>Action</b> -> <b>Pitch Undercut</b> to create an <em>Invisible</em> path beneath it connected by two <em>Connective</em> paths, which can be used for connecting a passage that breaks through the wall below the pitch. This is necessary because you cannot connect three areas to one path.</p> <p>Select an area and do <b>Display</b> -> <b>Thin Z Selection</b> to restrict the drawing to a Z-range close to that which was selected. Expand this visible area using <b>Display</b> -> <b>Widen Z Selection</b>. A vertical bar on the left of the graphics area depicts the Z-region in view and selected. </p> <p>The altitudes of centreline stations can be shown using <b>Display</b> -> <b>Station Altitudes</b>. Do <b>Colour</b> -> <b>Height</b> to fill in a colour spectrum of heights those visible in the graphics window at the time (zoom in to a small section of the cave to exaggerate the colour spread for that part).</p> <h1>Symbols</h1> <p>Symbols are placed on <em>Connective</em> paths. They are always part of the area they point into from the node they join (though the rest of the path can go outside the area).</p> <p>Click on <b>Add Symbols</b> and select the chosen symbol. Some are single symbols (eg stalactite, straws), directional (eg slope, stream), and the rest are area filling (eg puddle, boulders). To render, first <b>Update Areas</b> to bind the symbols into the correct area, and then <b>Update Symbols</b> to lay them out.</p> <p>The <b>subs</b> tab allows for setting the subset style for rendering the symbols to different scales.</p> <h1>Symbol files</h1> <p>The symbols directory contains all the basic symbols in the form of little sketches (eg a single boulder, one stream arrow, etc). You can see and edit them them by doing <b>Tunnel</b> -> <b>Symbols list</b> from the MainBox.</p> <p>The <em>fontcolours.xml</em> files contain the real work of defining what happens for each Subset Style. For example, the baseSymbols250 style defines:</p> <p><pre><symbolaut dname="stream" description="stream symbol" multiplicity="1" buttonaction="overwrite" area-interaction="allowed-outside" position="endpath" scale="fixed" orientation="fixed"> <asymbol name="stream" picscale="0.5" orientation="nearaxis"/> </symbolaut> </pre></p> <p>A symbol (usually a puddle) can be set to a solid fill colour using the parameter <tt>symbolareafillcolour="#ff0000ff"</tt>.</p> <p>The <em>symbols</em> directory will be loaded from <tt>[current-directory]/symbols</tt> if it exists, or <tt>[home-directory]/.tunnelx/symbols</tt> (if in unix) or <tt>[home-directory]/symbols</tt> (if in windows), or finally <tt>/usr/share/tunnelx/symbols/</tt>. If none of these exist, it will use the symbols directory that comes with the <em>.jar</em> file.</p> <h1>Labels</h1> <p>Labels are placed on <em>Connective</em> paths. Click on <b>Write Text</b> and write the label in the text area, selecting the type of label from the drop down box.</p> <p>The origin position is located at the first node of the path. The 3x3 choice matrix sets which corner or side of the box containing the text is placed on the origin. Fine positioning can be done by drawing a short path from the first node and clicking <b>Fuse</b>.</p> <p>Always connect one end to the associated passage so it stays with in place when the passage is moved.</p> <p>Use the <b>Arrow</b> selection to point at one end, and the <b>Box</b> to further highlight a label.</p> <h1>Scale bars</h1> <p>Paste one of the following blocks of text into a label to produce a scale bar. Simple version:</p> <tt><ul> <li>%10/1.0000%%whiterect%</li> <li>;%10/%%blackrect%</li> <li>;%10/%%whiterect%</li> <li>;%10/%%blackrect%</li> <li>;%10/%%whiterect%</li> <li>%v1.0/1%</li> <li>%10/%0m</li> <li>;%10/%10m</li> <li>;%10/%20m</li> <li>;%10/%30m</li> <li>;%10/%40m</li> <li>;%10/%50m</li> </ul></tt> <p>Complex scale bar:</p> <tt><ul> <li>%0/1.0000%%v0/%</li> <li>;%50/%%v1/%%whiterect%</li> <li>%1/%%v0.5/%</li> <li>;%1/%%v0.5/%%blackrect%</li> <li>;%1/%</li> <li>;%1/%%v0.5/%%blackrect%</li> <li>;%1/%</li> <li>;%5/%%v0.5/%%blackrect%</li> <li>;%5/%%v1/%</li> <li>;%5/%%v0.5/%%blackrect%</li> <li>;%5/%%v1/%</li> <li>;%5/%%v0.5/%%blackrect%</li> <li>;%5/%%v1/%</li> <li>;%5/%%v0.5/%%blackrect%</li> <li>;%5/%%v1/%</li> <li>;%5/%%v0.5/%%blackrect%</li> <li>%1/%%v0.5/%%blackrect%</li> <li>;%1/%</li> <li>;%1/%%v0.5/%%blackrect%</li> <li>;%1/%</li> <li>;%1/%%v0.5/%%blackrect%</li> <li>;%5/%</li> <li>;%5/%%v0.5/%%blackrect%</li> <li>;%5/%</li> <li>;%5/%%v0.5/%%blackrect%</li> <li>;%5/%</li> <li>;%5/%%v0.5/%%blackrect%</li> <li>;%5/%</li> <li>;%5/%%v0.5/%%blackrect%</li> <li>%v0.8/%</li> <li>%4.5/%0m</li> <li>;%5/%5m</li> <li>;%10/%10m</li> <li>;%10/%20m</li> <li>;%10/%30m</li> <li>;%10/%40m</li> <li>;%10/%50m</li> </ul></tt> <p>North arrow:</p> <tt><ul> <li>N</li> <li>%t1/0.1%%v0/%%h0/%</li> <li>;%v3/%%t0/%%h2/%%whiterect%</li> <li>%t1/%%v0/%%h0/%</li> <li>;%v3/%%t0/%%h1/%%blackrect%</li> </ul></tt> <p>Left arrow:</p> <tt><ul> <li>%t2/0.1%%v0/%%h0/%</li> <li>;%v0.5/%%t0/%%h2/%%whiterect%</li> <li>%v0.5/0.1%</li> <li>%v0.5/%%t0/%%h2/%</li> <li>;%v0.5/%%t2/%%h0/%%blackrect%</li> </ul></tt> <p>Depth scale bar:</p> <tt><ul> <li>%10/3%%v50/%%blackrect%</li> <li>;1800m</li> <li>%10/%%v50.0/%%whiterect%</li> <li>;1600m</li> <li>%10/%%v50/%%blackrect%</li> <li>;1500m</li> <li>%10/%%v50.0/%%whiterect%</li> <li>;1400m</li> <li>%10/%%v50/%%blackrect%</li> <li>;1300m</li> <li>%10/%%v50.0/%%whiterect%</li> <li>;1200m</li> <li>%10/%%v50/%%blackrect%</li> <li>;1100m</li> <li>%10/%%v0/%</li> <li>;1700m</li> </ul></tt> <p>The <b>';'</b> at the start of the line means the block stays on the same row. (each new line is displaced down by the vertical height of the first block). The code <b>'%X/Y%'</b> at the beginning of a block makes it have a width of <em>X/Y</em> metres, while <b>'%vX/Y'</b> sets its height. (If <b>'Y'</b> is left out, then it takes the previous value, so in the first example the 50m scale bar can be converted to a 500m scale bar by changing <tt>1.0000</tt> to <tt>0.1</tt> in the first line.)</p> <p>The symbols <b>'%whiterect%'</b> and <b>'%blackrect%'</b> fill the block with an outline or a filled in rectangle. Alternatively, place text here and use the blocks to define the cells of a table.</p> <p>The top and bottom widths of a block can be set independently with <b>'%tX/Y'</b> for the top and <b>'%hX/Y'</b> for the bottom (the 'h' is optional) to produce triangles or parallelograms.</p> <h1>Info</h1> <p>Use the <b>info</b> panel to find information about paths. <p><b>Searching</b> - Fill in the text box and click <em>search</em> to produce a list of labels the text appears in. Click on the label to select the path.</p> <p><b>Making new paths</b> - Comma or space separated list in the same search box, then click on <em>New nodes</em> to add these nodes to the drawn path.</p> <h1>Subsets</h1> <p>The current subset can be selected from the tree view in <b>subs</b> tab. Select a colour beneath the '<tt>visiblesets</tt>' and all the paths will turn grey. Select a path (<em>Mouse Right</em>) or an area (<em>Shift+Mouse Right</em>) and click <b>Add to Subset</b> to make it appear in the subset. Labels should be added to the subset, but their colours will only show after clicking <b>Detail Render</b>. <p>Do <b>Clear subset selection</b> to undo the subset selection. The subsets of a selected path appears in the drop-down box at the bottom, which can be used for quick selection of an individual subset.</p> <p>Named subsets can be made by making a <em>Connective</em> path, clicking <b>Area signal</b>, and choosing <em>frame</em> from the drop-down box. Above the line <tt>'</sketchframe>'</tt> (the last line), insert:</p> <ul><li> <tt><subsetattr uppersubset="blue" name="Secret Grotto"/></tt> </li></ul> <p>... then click <b>Copy</b>. The tree view in the lower window will now have '<tt>(Secret Grotto)</tt>' beneath '<tt>visiblesets</tt>' -> '<tt>blue</tt>'. Select it to add paths and areas to the 'Secret Grotto' subset. The colour can be altered later by changing the value of '<tt>uppersubset</tt>'. The colour set when '<tt>name="default"</tt>' applies to all remaining areas.</p> <h1>Frame</h1> <p>Start a new empty sketch, and make a <em>Connective</em> path, click <b>Area signal</b> and selecting <em>frame</em> from the drop-down box. Now click <b>Import</b> -> <b>Import paper</b> -> <b>Make A1</b> to create an <em>A1</em> size sheet of paper.</p> <p>Draw a rectangle in it, make a path into it, and make it <em>frame</em> type too. Now we can add another sketch to it, apply Max, move it around into position, set its colours, and render it.</p> <p>It's possible to render the same survey at two different scales in the same area with different subset styles overlaid on a aerial photo or bitmap of a map.</p> <p>Also put in all the title box and other clobber in this, so as not to clutter the main survey with it. Use <em>subset style</em> <tt>baseA3page</tt> or similar to find a new set of fonts.</p> <p>Images can be placed inside areas (as well as other sketches) where they will be trimmed. This allows for background overlays of aerial imagery.</p> <p>Multiple sketchs can appear in the same window, where the order is controlled by setting the <em>nodeconnzsetrelative</em> values.</p> <h1>DistoX TOP files</h1> <p>DistoX laser and compass devices that transmit their measurements to a Windows PDA via bluetooth saves its data into a binary <b>.top</b> file which contains the survey legs, plan drawing and elevation drawing in three separate sections.</p> <p>You can open a .top file by doing <b>File</b> -> <b>Open survex...</b> from the Main window and selecting it. This will open both plan and elevation drawings into the same sketch and put the survey data into the label of the big green 'S'.</p> <p>Unfortunately, this TOP file cannot be used natively in TunnelX because the lines tend to be disconnected and sketchy, so you will need to copy and paste the Survex data into its own text file and link it into the rest of the data by hand, and then render the drawings into two .png files by selecting the <b>subs</b> tab, then picking <em>plan_TOP</em> in the <em>_Unattributed_</em> folder before going to the <b>print</b> tab and rendering the image to a PNG file. (Don't forget to reset the dots/inch to a higher value for a better quality image.) Do the same for the <em>elev_TOP</em> subset. It is important for the subset style to be "pockettopo" for the colours to come out. Now you can reload the whole survex file and add the rendering as the background image ready to be traced over.</p> <p>To render the elevation centreline from a TOP survex file, open the .svx file from the Main window and click <b>Back</b> to get rid of the plan view. Now you can do <b>Import</b> -> <b>Import Centreline Elev</b> to generate the extended elevation of this centreline. The legs that contain <em>flip_TOP</em> are oriented left to right, as well as any legs that have their tail visited first during the traversal from the starting point (which is either the first point in the survey, or the nearest fixed point). </p> </p> <h1>Elevations</h1> <p><em>Provisional owing to user interface difficulties</em></p> <p>Drawings for cross sections and extended elevations are tied to a <em>Connective</em> path by all being in a subset of name "XC stationname" or "ELEV stationname1 stationname2".</p> <p>To make a cross section, draw a <em>Connective</em> line from a node in one wall across the passage into a node in the other wall. Then (with the path selected) do <b>Elevation</b> -> <b>XC Subset</b> to create the new subset (with a name of the form "XC something") and the axis of the cross section (as a disconnected centreline piece). Move and fit this axis to the cross section (using <b>Fuse</b> and <b>Component</b>) and then draw around the cross section (connecting it to the axis). Note that an arrow pointer moves along the corresponding path cutting the passage for the purpose of lining up features between the plan and the cross section.</p> <p>To make an extended elevation, draw a <em>Connective</em> line from a centreline node (or a node immediately connected to a centreline) to another such node, then do <b>Elevation</b> -> <b>Elevation Subset</b> to generate a long centreline path for use as the axis in the elevation drawing.</p> <p>After the elevation has been drawn (with all the paths in the "ELEV" subset), the endpoint of the centreline axis can be moved (using <b>Fuse</b>) to stretch and fit the pieces together.</p> <p>Use the <b>img</b> tab to see what is happening when the elevation/cross section drawing and corresponding place in the plan are too far apart to show in the same graphics area at a resonable scale.</p> <h1>Printing</h1> <p>The <b>print</b> tab enables output to PNG or JPG type images, which can then be printed using standard image handling software. The printing area is either the bounding box for the currently selected subset (set through the <b>subs</b> tab), or the viewable graphics area. Select the subset for the <em>A1 frame</em> to produce a consistent result.</p> <p>The dimensions stated in <em>Real dimensions:</em> correspond to a baseline scale of <tt>1:1000</tt>, so a 500m wide cave will be 50cm on the paper. Vary the pixel dimensions by changing the resolution in dots per inch (on this 1:1000 paper).</p> <p>The directory for output and name of file are listed below.</p> <p>Because the same sketch may appear as in different <em>subset styles</em>, a proper rendering may require the symbols to be layed out multiple times. Select <em>Full draw</em> to enable this, or preview using one of the lesser modes.</p> <p>Other options include output to <em>Gray scale</em> and <em>Transparent</em> colour to make the white areas alpha=0 for use in other graphics packages.</p> <p><em>Requires re-implementation:</em> If the centreline is in the right coordinate space, click on <b>Overlay</b> to render it and upload it to the cave map overlay automatically, for maximum speed of publication.</p> <h1>Command line</h1> <p>To compile do:</p> <p><tt>"C:\Program Files\Java\jdk1.6.0_26\bin\javac" -target 1.5 -Xlint:deprecation -d . src\*.java</tt></p> <p>To run do:</p> <p><tt>java -showversion -ea -Xmx1000M -cp . Tunnel.MainBox C:\\Users\\goatchurch\\tunneldata\\</tt></p> <p>Other options:</p> <ul> <li><tt>--verbose</tt></li> <li><tt>--quiet</tt></li> <li><tt>--todenode</tt></li> <li><tt>--netconnection</tt></li> <li><tt>--makeimages</tt> Automatically generates images from all the areas that have an areasignal of frame and subset "framestyle"</li> <li><tt>--printdir=</tt></li> <li><tt>--twotone</tt> Forces a grey scale which is mapped to black and white pixels at a threshold of 65000</li> </ul> <h1>Main - Start here</h1> <p>Welcome to TunnelX, a free Cave drawing system that depends on Survex and which does the same thing as Therion, except completely different. See <b>https://bitbucket.org/goatchurch/tunnelx</b> for updates and development.</p> <p>If this is your first time using TunnelX, try opening the tutorials and double-clicking on the first one.</p> <p>Updated 2012-06-01</p>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/triangleboulder.xml���������������������������������������������������0000755�0000000�0000000�00000002032�12066375447�016701� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:09"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="centreline"> <pt X="2109.4912" Y="-325.29443"/> <pt X="2119.787" Y="-324.8618"/> </skpath> <skpath from="2" to="2" linestyle="detail"> <pt X="2111.4812" Y="-328.03424"/> <pt X="2110.0103" Y="-321.48746"/> <pt X="2119.5564" Y="-325.2079"/> <pt X="2111.4812" Y="-328.03424"/> </skpath> <skpath from="0" to="0" linestyle="invisible"> <pt X="2109.4912" Y="-325.29443"/> <pt X="2108.3357" Y="-319.75595"/> <pt X="2122.3052" Y="-325.08295"/> <pt X="2111.0552" Y="-329.5159"/> <pt X="2109.4912" Y="-325.29443"/> </skpath> <skpath from="0" to="2" linestyle="invisible" splined="1"> <pt X="2109.4912" Y="-325.29443"/> <pt X="2111.4812" Y="-328.03424"/> </skpath> </sketch> </tunnelxml> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/slope.xml�������������������������������������������������������������0000755�0000000�0000000�00000001256�12066375447�014650� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:09"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="0" linestyle="filled"> <pt X="2121.5808" Y="-324.7555"/> <pt X="2108.3567" Y="-321.59113"/> <pt X="2109.915" Y="-324.7555"/> <pt X="2108.3567" Y="-327.73096"/> <pt X="2121.5808" Y="-324.7555"/> </skpath> <skpath from="1" to="0" linestyle="centreline"> <pt X="2109.9624" Y="-324.8027"/> <pt X="2121.5808" Y="-324.7555"/> </skpath> </sketch> </tunnelxml> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/stream.xml������������������������������������������������������������0000755�0000000�0000000�00000003267�12066375447�015025� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:09"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="centreline"> <pt X="2111.096" Y="-331.7854"/> <pt X="2125.2227" Y="-331.5821"/> </skpath> <skpath from="2" to="1" linestyle="detail" splined="1"> <pt X="2123.0747" Y="-334.19568"/> <pt X="2125.2227" Y="-331.5821"/> </skpath> <skpath from="3" to="1" linestyle="detail" splined="1"> <pt X="2123.0747" Y="-329.39603"/> <pt X="2125.2227" Y="-331.5821"/> </skpath> <skpath from="1" to="0" linestyle="detail" splined="1"> <pt X="2125.2227" Y="-331.5821"/> <pt X="2122.329" Y="-331.81915"/> <pt X="2119.999" Y="-333.5899"/> <pt X="2117.2031" Y="-330.1416"/> <pt X="2115.0596" Y="-333.68307"/> <pt X="2112.9163" Y="-331.95895"/> <pt X="2111.096" Y="-331.7854"/> </skpath> <skpath from="4" to="4" linestyle="invisible"> <pt X="2110.1584" Y="-331.78174"/> <pt X="2110.6245" Y="-330.3479"/> <pt X="2115.4995" Y="-329.5593"/> <pt X="2120.5898" Y="-329.2367"/> <pt X="2122.4895" Y="-328.16132"/> <pt X="2124.4612" Y="-328.7707"/> <pt X="2126.0383" Y="-331.17236"/> <pt X="2125.5007" Y="-333.64572"/> <pt X="2122.9556" Y="-334.97202"/> <pt X="2114.1733" Y="-334.54187"/> <pt X="2110.8755" Y="-333.3948"/> <pt X="2110.1584" Y="-331.78174"/> </skpath> <skpath from="0" to="4" linestyle="invisible" splined="1"> <pt X="2111.096" Y="-331.7854"/> <pt X="2110.1584" Y="-331.78174"/> </skpath> </sketch> </tunnelxml> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/stalboss.xml����������������������������������������������������������0000644�0000000�0000000�00000007161�12066375447�015356� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:09"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="centreline"> <pt X="2114.232" Y="-329.017"/> <pt X="2114.3896" Y="-323.4041"/> </skpath> <skpath from="2" to="3" linestyle="detail" splined="1"> <pt X="2112.043" Y="-323.91577"/> <pt X="2112.6868" Y="-323.1834"/> <pt X="2114.2634" Y="-322.64734"/> <pt X="2115.9348" Y="-322.67886"/> <pt X="2117.0068" Y="-323.12033"/> <pt X="2117.6375" Y="-323.9402"/> </skpath> <skpath from="4" to="5" linestyle="detail" splined="1"> <pt X="2112.6228" Y="-324.55237"/> <pt X="2110.867" Y="-325.01776"/> <pt X="2110.6343" Y="-326.47748"/> <pt X="2110.8882" Y="-327.61987"/> <pt X="2111.5862" Y="-328.14874"/> </skpath> <skpath from="6" to="6" linestyle="detail" splined="1"> <pt X="2114.4211" Y="-327.1756"/> <pt X="2113.215" Y="-326.73135"/> <pt X="2113.596" Y="-325.69473"/> <pt X="2114.9287" Y="-325.65244"/> <pt X="2115.3943" Y="-326.414"/> <pt X="2114.4211" Y="-327.1756"/> </skpath> <skpath from="7" to="8" linestyle="detail" splined="1"> <pt X="2112.2844" Y="-328.00064"/> <pt X="2112.3054" Y="-329.26996"/> <pt X="2113.215" Y="-330.13733"/> <pt X="2115.5422" Y="-330.03156"/> <pt X="2116.4941" Y="-329.2488"/> <pt X="2116.452" Y="-328.1064"/> </skpath> <skpath from="9" to="10" linestyle="detail" splined="1"> <pt X="2117.1482" Y="-328.668"/> <pt X="2118.5906" Y="-328.09103"/> <pt X="2119.2317" Y="-327.00122"/> <pt X="2119.2957" Y="-325.20624"/> <pt X="2117.7893" Y="-324.59723"/> </skpath> <skpath from="11" to="12" linestyle="detail" splined="1"> <pt X="2114.648" Y="-324.72543"/> <pt X="2116.2444" Y="-324.33658"/> <pt X="2117.6257" Y="-325.53247"/> <pt X="2117.02" Y="-326.8089"/> </skpath> <skpath from="5" to="7" linestyle="invisible" splined="1"> <pt X="2111.5862" Y="-328.14874"/> <pt X="2112.2844" Y="-328.00064"/> </skpath> <skpath from="5" to="13" linestyle="invisible" splined="1"> <pt X="2111.5862" Y="-328.14874"/> <pt X="2110.8015" Y="-328.95648"/> </skpath> <skpath from="13" to="13" linestyle="invisible" splined="1"> <pt X="2110.8015" Y="-328.95648"/> <pt X="2112.7249" Y="-330.87967"/> <pt X="2116.0583" Y="-331.1361"/> <pt X="2118.5264" Y="-329.24496"/> <pt X="2120.1611" Y="-326.8089"/> <pt X="2120.2573" Y="-325.14212"/> <pt X="2118.943" Y="-324.08438"/> <pt X="2116.8916" Y="-322.2894"/> <pt X="2113.9106" Y="-321.68036"/> <pt X="2111.8274" Y="-322.77017"/> <pt X="2110.5132" Y="-324.2126"/> <pt X="2109.8079" Y="-326.0717"/> <pt X="2110.2566" Y="-327.7705"/> <pt X="2110.8015" Y="-328.95648"/> </skpath> <skpath from="4" to="2" linestyle="invisible" splined="1"> <pt X="2112.6228" Y="-324.55237"/> <pt X="2112.043" Y="-323.91577"/> </skpath> <skpath from="6" to="7" linestyle="invisible" splined="1"> <pt X="2114.4211" Y="-327.1756"/> <pt X="2112.2844" Y="-328.00064"/> </skpath> <skpath from="8" to="9" linestyle="invisible" splined="1"> <pt X="2116.452" Y="-328.1064"/> <pt X="2117.1482" Y="-328.668"/> </skpath> <skpath from="10" to="3" linestyle="invisible" splined="1"> <pt X="2117.7893" Y="-324.59723"/> <pt X="2117.6375" Y="-323.9402"/> </skpath> <skpath from="4" to="11" linestyle="invisible" splined="1"> <pt X="2112.6228" Y="-324.55237"/> <pt X="2114.648" Y="-324.72543"/> </skpath> </sketch> </tunnelxml> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/fontcolours_b.xml�����������������������������������������������������0000644�0000000�0000000�00000061046�12261213471�016365� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml> <fontcolours fontstyle="PLAIN" fontname="Serif"> <groupsubsetattr groupsubsetname="base250"> <importgroupsubsetattr groupsubsetname="base"/> <importgroupsubsetattr groupsubsetname="baseSymbols250"/> <subsetattr name="visiblesets" areamaskcolour="#7bffffff" areacolour="#66cce5e5" strokecolour="#ff000000" fontstyle="PLAIN" labelcolour="$labcolour"> <setvariable name="$labcolour" value="#ff000000"/> <labelfcol labelstylename="default"/> <labelfcol labelstylename="qm" size="18"/> <labelfcol labelstylename="step" fontstyle="ITALIC" size="20"/> <labelfcol labelstylename="note" fontname="Franklin Gothic Medium" fontstyle="" size="4"/> <labelfcol labelstylename="passage" fontname="Franklin Gothic Medium" fontstyle="BOLD" size="24"/> <labelfcol labelstylename="entrance" fontname="Franklin Gothic Medium" size="15.0"/> <labelfcol labelstylename="area" fontname="Franklin Gothic Medium" fontstyle="ITALIC" size="34.375"/> <labelfcol labelstylename="cave" fontname="Franklin Gothic Medium" fontstyle="BOLD" size="96.375"/> <labelfcol labelstylename="label" fontname="Franklin Gothic Medium" fontstyle="BOLD" size="50"/> <labelfcol labelstylename="survey" fontname="Arial" fontstyle="BOLD" size="20.0" labelcolour="none"/> <linestylecol linestyle="centreline" strokewidth="0.15" strokecolour="#ff800000"/> <linestylecol linestyle="wall" strokewidth="0.65"/> <linestylecol linestyle="estwall" strokewidth="0.65" spikegap="2.5" gapleng="1.75" spikeheight="0.0" strokecolour="#ff000000"/> <linestylecol linestyle="pitchbound" strokewidth="0.31" spikegap="2.5" gapleng="0.0" spikeheight="2.5"/> <linestylecol linestyle="ceilingbound" strokewidth="0.31" spikegap="2.5" gapleng="1.5" spikeheight="1.5"/> <linestylecol linestyle="detail" strokewidth="0.31"/> <linestylecol linestyle="filled" strokewidth="0.0" strokecolour="#ff000080"/> </subsetattr> <subsetattr name="greyed" uppersubset="obscuredsets" labelcolour="none" areamaskcolour="#4bffffff" areacolour="#369caae5"> <linestylecol linestyle="wall" strokewidth="2.25" strokecolour="#66808080"/> <linestylecol linestyle="estwall" strokewidth="2.25" spikegap="7.5" gapleng="3.75" spikeheight="0.0" strokecolour="#66808080"/> <set multiplicity="fill" position="latticef" area-interaction="trim" buttonaction="overwrite" scale="fixed" orientation="fixed"> <symbolaut dname="puddle" picscale="1.0" description="water area"> <asymbol name="puddle"/> </symbolaut> <symbolaut dname="sump" picscale="1.0" description="9x9sump"> <asymbol name="sump"/> </symbolaut> </set> </subsetattr> <importgroupsubsetattr groupsubsetname="planecolours"/> <subsetattr name="default" uppersubset="visiblesets"/> </groupsubsetattr> <groupsubsetattr groupsubsetname="base250nonote"> <importgroupsubsetattr groupsubsetname="base250"/> <subsetattr name="visiblesets" areamaskcolour="#7bffffff" areacolour="#66cce5e5" strokecolour="#ff000000" fontstyle="PLAIN" labelcolour="$labcolour"> <labelfcol labelstylename="note" labelcolour="none"/> <linestylecol linestyle="centreline" strokewidth="0.15" strokecolour="none"/> </subsetattr> </groupsubsetattr> <groupsubsetattr groupsubsetname="base250faded"> <importgroupsubsetattr groupsubsetname="base250"/> <subsetattr name="visiblesets" areamaskcolour="#7bffffff" areacolour="#66ffe5e5" strokecolour="#50000000" fontstyle="PLAIN" labelcolour="#70111199"> <linestylecol linestyle="centreline" strokewidth="0.312" strokecolour="#fff00000"/> <linestylecol linestyle="wall" strokewidth="1.25"/> <linestylecol linestyle="estwall" strokewidth="1.25" spikegap="7.5" gapleng="3.75" spikeheight="0.0"/> <linestylecol linestyle="pitchbound" strokewidth="0.625" spikegap="7.5" gapleng="0.0" spikeheight="2.5"/> <linestylecol linestyle="ceilingbound" strokewidth="0.625" spikegap="7.5" gapleng="2.5" spikeheight="2.5"/> <linestylecol linestyle="detail" strokewidth="0.625"/> </subsetattr> <subsetattr name="red" uppersubset="visiblesets" areacolour="#55e53344"> <setvariable name="$labcolour" value="#70b50023"/> </subsetattr> <subsetattr name="orange" uppersubset="visiblesets" areacolour="#55ff9900"> <setvariable name="$labcolour" value="#70ff9900"/> </subsetattr> <subsetattr name="yellow" uppersubset="visiblesets" areacolour="#55bbde00"> <setvariable name="$labcolour" value="#709bae00"/> </subsetattr> <subsetattr name="cyan" uppersubset="visiblesets" areacolour="#5550ffff"> <setvariable name="$labcolour" value="#7000aaaa"/> </subsetattr> <subsetattr name="green" uppersubset="visiblesets" areacolour="#5529ff3d"> <setvariable name="$labcolour" value="#7009bf1d"/> </subsetattr> <subsetattr name="blue" uppersubset="visiblesets" areacolour="#555555ff"> <setvariable name="$labcolour" value="#700033ff"/> </subsetattr> <subsetattr name="purple" uppersubset="visiblesets" areacolour="#55a900e5"> <setvariable name="$labcolour" value="#70a900e5"/> </subsetattr> <subsetattr name="magenta" uppersubset="visiblesets" areacolour="#55ff00ff"> <setvariable name="$labcolour" value="#70cc00cc"/> </subsetattr> <subsetattr name="green2" uppersubset="visiblesets" areacolour="#5519ff2d"> <setvariable name="$labcolour" value="#7019ff2d"/> </subsetattr> <subsetattr name="blue2" uppersubset="visiblesets" areacolour="#550033ff"> <setvariable name="$labcolour" value="#700033ff"/> </subsetattr> <subsetattr name="purple2" uppersubset="visiblesets" areacolour="#55a900e5"> <setvariable name="$labcolour" value="#70a900e5"/> </subsetattr> <subsetattr name="red2" uppersubset="visiblesets" areacolour="#55e50033"> <setvariable name="$labcolour" value="#70e50033"/> </subsetattr> <subsetattr name="yellow2" uppersubset="visiblesets" areacolour="#55ccff00"> <setvariable name="$labcolour" value="#70bbee00"/> </subsetattr> <subsetattr name="strongrey" uppersubset="visiblesets" areacolour="#55808080"> <setvariable name="$labcolour" value="#70707070"/> </subsetattr> <subsetattr name="brightgrey" uppersubset="visiblesets" areacolour="#55ffffff"> <setvariable name="$labcolour" value="#70606060"/> </subsetattr> </groupsubsetattr> <groupsubsetattr groupsubsetname="base500"> <importgroupsubsetattr groupsubsetname="base"/> <importgroupsubsetattr groupsubsetname="baseSymbols500"/> <subsetattr name="visiblesets" areamaskcolour="#7bffffff" areacolour="#66cce5e5" strokecolour="#ff000000" fontstyle="PLAIN" labelcolour="$labcolour"> <setvariable name="$labcolour" value="#ff000000"/> <labelfcol labelstylename="default"/> <labelfcol labelstylename="qm" size="9.375"/> <labelfcol labelstylename="step" fontstyle="ITALIC" size="12.5"/> <labelfcol labelstylename="passage" fontstyle="BOLD" size="23"/> <labelfcol labelstylename="entrance" fontname="Franklin Gothic Medium" size="30.0"/> <labelfcol labelstylename="area" fontname="Franklin Gothic Medium" fontstyle="ITALIC" size="34.375"/> <labelfcol labelstylename="cave" fontname="Franklin Gothic Medium" fontstyle="BOLD" size="96.375"/> <labelfcol labelstylename="survey" fontname="Arial" fontstyle="BOLD" size="20.0" labelcolour="none"/> <labelfcol labelstylename="note" labelcolour="none"/> <linestylecol linestyle="centreline" strokewidth="0.312" strokecolour="#ff800000"/> <linestylecol linestyle="wall" strokewidth="1.25"/> <linestylecol linestyle="estwall" strokewidth="1.25" spikegap="7.5" gapleng="3.75" spikeheight="0.0" strokecolour="#ff000000"/> <linestylecol linestyle="pitchbound" strokewidth="0.625" spikegap="7.5" gapleng="0.0" spikeheight="2.5"/> <linestylecol linestyle="ceilingbound" strokewidth="0.625" spikegap="7.5" gapleng="2.5" spikeheight="2.5"/> <linestylecol linestyle="detail" strokewidth="0.625"/> <linestylecol linestyle="filled" strokewidth="0.0" strokecolour="#ff000080"/> </subsetattr> <subsetattr name="greyed" uppersubset="obscuredsets" labelcolour="none" areamaskcolour="#4bffffff" areacolour="#369caae5"> <linestylecol linestyle="wall" strokewidth="2.25" strokecolour="#66808080"/> <linestylecol linestyle="estwall" strokewidth="2.25" spikegap="7.5" gapleng="3.75" spikeheight="0.0" strokecolour="#66808080"/> </subsetattr> <importgroupsubsetattr groupsubsetname="planecolours"/> <subsetattr name="default" uppersubset="visiblesets"/> </groupsubsetattr> <groupsubsetattr groupsubsetname="base500descent"> <importgroupsubsetattr groupsubsetname="base"/> <subsetattr name="visiblesets" areamaskcolour="#7bffffff" areacolour="#66cce5e5" strokecolour="#ff000000" fontstyle="PLAIN" labelcolour="$labcolour"> <set multiplicity="1" buttonaction="overwrite" area-interaction="allowed-outside" position="endpath" scale="fixed" orientation="fixed"> <symbolaut dname="slope2" description="big slope symbol"> <asymbol name="slope" picscale="1.1" orientation="alongaxis" drawstyle="filled"/> </symbolaut> </set> <setvariable name="$labcolour" value="#ff000000"/> <labelfcol labelstylename="default" labelcolour="none"/> <labelfcol labelstylename="note" labelcolour="none"/> <labelfcol labelstylename="qm" labelcolour="none"/> <labelfcol labelstylename="step" labelcolour="none"/> <labelfcol labelstylename="passage" fontname="Arial" size="23"/> <labelfcol labelstylename="entrance" fontname="Arial" size="30.0"/> <labelfcol labelstylename="area" fontname="Arial" size="34.375"/> <labelfcol labelstylename="cave" fontname="Arial" size="96.375"/> <labelfcol labelstylename="survey" labelcolour="none"/> <linestylecol linestyle="centreline" strokewidth="0.15" strokecolour="none"/> <linestylecol linestyle="wall" strokewidth="0.20"/> <linestylecol linestyle="estwall" strokewidth="0.20" spikegap="7.5" gapleng="3.75" spikeheight="0.0" strokecolour="#ff000000"/> <linestylecol linestyle="pitchbound" strokewidth="0.18" spikegap="7.5" gapleng="0.0" spikeheight="2.5"/> <linestylecol linestyle="ceilingbound" strokewidth="0.18" spikegap="7.5" gapleng="2.5" spikeheight="2.5"/> <linestylecol linestyle="detail" strokewidth="0.18"/> <linestylecol linestyle="filled" strokewidth="0.0" strokecolour="#ff000000"/> </subsetattr> <importgroupsubsetattr groupsubsetname="planecolours"/> <subsetattr name="green" uppersubset="visiblesets" areacolour="#8819ff2d"> <setvariable name="$labcolour" value="#ff19ff2d"/> </subsetattr> <subsetattr name="default" uppersubset="visiblesets"/> </groupsubsetattr> <groupsubsetattr groupsubsetname="base1000" groupsubsetselectable="yes"> <importgroupsubsetattr groupsubsetname="base"/> <importgroupsubsetattr groupsubsetname="baseSymbols1000"/> <subsetattr name="visiblesets" areamaskcolour="#7bffffff" areacolour="#66cce5e5" strokecolour="#ff000000" fontstyle="PLAIN" labelcolour="$labcolour"> <setvariable name="$labcolour" value="#ff000000"/> <labelfcol labelstylename="default"/> <labelfcol labelstylename="qm" size="40.0" labelcolour="none"/> <labelfcol labelstylename="step" fontstyle="ITALIC" size="80.0" labelcolour="#ff000000"/> <labelfcol labelstylename="passage" fontstyle="BOLD" size="110.0" labelcolour="#ff000000"/> <labelfcol labelstylename="feature" size="60.0"/> <labelfcol labelstylename="entrance" fontname="Franklin Gothic Medium" size="60.0"/> <labelfcol labelstylename="area" fontname="Franklin Gothic Medium" fontstyle="ITALIC" size="95.0"/> <labelfcol labelstylename="cave" fontname="Franklin Gothic Medium" fontstyle="BOLD" size="96.375"/> <labelfcol labelstylename="description" size="5.0"/> <labelfcol labelstylename="survey" fontname="Arial" fontstyle="BOLD" size="20.0" labelcolour="none"/> <linestylecol linestyle="centreline" strokewidth="0.312" strokecolour="#ff800000"/> <linestylecol linestyle="wall" strokewidth="2.25"/> <linestylecol linestyle="estwall" strokewidth="2.25" spikegap="7.5" gapleng="3.75" spikeheight="0.0"/> <linestylecol linestyle="pitchbound" strokewidth="1.225" spikegap="9.5" gapleng="0.0" spikeheight="4.5"/> <linestylecol linestyle="ceilingbound" strokewidth="1.225" spikegap="9.5" gapleng="2.5" spikeheight="4.0"/> <linestylecol linestyle="detail" strokewidth="1.225"/> <linestylecol linestyle="filled" strokewidth="0.0" strokecolour="#ff000080"/> </subsetattr> <subsetattr name="greyed" uppersubset="obscuredsets" labelcolour="none" areamaskcolour="#4bffffff" areacolour="#369caae5"> <linestylecol linestyle="wall" strokewidth="2.25" strokecolour="#66808080"/> <linestylecol linestyle="estwall" strokewidth="2.25" spikegap="7.5" gapleng="3.75" spikeheight="0.0" strokecolour="#66808080"/> </subsetattr> <importgroupsubsetattr groupsubsetname="planecolours"/> <subsetattr name="default" uppersubset="visiblesets"/> </groupsubsetattr> <groupsubsetattr groupsubsetname="baseBW4000"> <importgroupsubsetattr groupsubsetname="base"/> <importgroupsubsetattr groupsubsetname="baseSymbols4000"/> <subsetattr name="visiblesets" areamaskcolour="#7bffffff" areacolour="#664c4c4c" strokecolour="#ff000000" fontstyle="PLAIN" labelcolour="$labcolour"> <setvariable name="$labcolour" value="#ff000000"/> <labelfcol labelstylename="default" labelcolour="none"/> <labelfcol labelstylename="qm" size="9.375" labelcolour="none"/> <labelfcol labelstylename="step" fontstyle="ITALIC" size="12.5" labelcolour="none"/> <labelfcol labelstylename="passage" fontstyle="BOLD" size="40" labelcolour="none"/> <labelfcol labelstylename="entrance" fontname="Arial" size="50.0" labelcolour="none"/> <labelfcol labelstylename="area" fontname="Arial" fontstyle="ITALIC" size="50.0" labelcolour="none"/> <labelfcol labelstylename="cave" fontname="Arial" fontstyle="BOLD" size="66.0" labelcolour="none"/> <labelfcol labelstylename="survey" fontname="Arial" fontstyle="BOLD" size="20.0" labelcolour="none"/> <linestylecol linestyle="centreline" strokewidth="0.312" strokecolour="none"/> <linestylecol linestyle="wall" strokewidth="7" shadowstrokewidth="14.0" shadowstrokecolour="#ffffffff"/> <linestylecol linestyle="estwall" strokewidth="7" spikegap="12.5" gapleng="5.75" spikeheight="0.0" shadowstrokewidth="14.0" shadowstrokecolour="#ffffffff"/> <linestylecol linestyle="pitchbound" strokewidth="5" spikegap="12.5" gapleng="0.0" spikeheight="5"/> <linestylecol linestyle="ceilingbound" strokewidth="0.625" spikegap="7.5" gapleng="2.5" spikeheight="2.5" strokecolour="none"/> <linestylecol linestyle="detail" strokewidth="5"/> <linestylecol linestyle="filled" strokewidth="0.0"/> </subsetattr> <importgroupsubsetattr groupsubsetname="planecolours"/> <subsetattr name="greyed" uppersubset="visiblesets" labelcolour="none" areamaskcolour="#4bffffff" areacolour="#447c7c7c" strokecolour="#44000000"> <linestylecol linestyle="wall" strokewidth="7" shadowstrokewidth="14.0" shadowstrokecolour="#ffffffff"/> <linestylecol linestyle="estwall" strokewidth="7" spikegap="12.5" gapleng="5.75" spikeheight="0.0" shadowstrokewidth="14.0" shadowstrokecolour="#ffffffff"/> <linestylecol linestyle="pitchbound" strokewidth="5" spikegap="12.5" gapleng="0.0" spikeheight="5"/> <linestylecol linestyle="ceilingbound" strokewidth="0.625" spikegap="7.5" gapleng="2.5" spikeheight="2.5" strokecolour="none"/> <linestylecol linestyle="detail" strokewidth="5"/> <linestylecol linestyle="filled" strokewidth="0.0"/> </subsetattr> <subsetattr name="default" uppersubset="visiblesets"/> </groupsubsetattr> <groupsubsetattr groupsubsetname="FatCentreline"> <importgroupsubsetattr groupsubsetname="baseBW4000"/> <importgroupsubsetattr groupsubsetname="baseSymbols4000"/> <subsetattr name="visiblesets" areamaskcolour="#7bffffff" areacolour="#664c4c4c" strokecolour="#ff000000" fontstyle="PLAIN" labelcolour="$labcolour"> <setvariable name="$labcolour" value="#ff000000"/> <linestylecol linestyle="centreline" strokewidth="49" strokecolour="$labcolour"/> <labelfcol labelstylename="label" fontname="Arial" fontstyle="BOLD" size="166.0" labelcolour="$labcolour"/> </subsetattr> <importgroupsubsetattr groupsubsetname="planecolours"/> <subsetattr name="default" uppersubset="visiblesets"/> </groupsubsetattr> <groupsubsetattr groupsubsetname="FatCentreline3"> <importgroupsubsetattr groupsubsetname="base"/> <subsetattr name="visiblesets" areamaskcolour="#7bffffff" areacolour="#664c4c4c" strokecolour="#ff000000" fontstyle="PLAIN" labelcolour="$labcolour"> <setvariable name="$labcolour" value="#ff000000"/> <linestylecol linestyle="centreline" strokewidth="69" strokecolour="$labcolour"/> <linestylecol linestyle="wall" strokecolour="none"/> <linestylecol linestyle="estwall" strokecolour="none"/> <linestylecol linestyle="pitchbound" strokecolour="none"/> <linestylecol linestyle="ceilingbound" strokecolour="none"/> <linestylecol linestyle="detail" strokecolour="none"/> <linestylecol linestyle="filled" strokecolour="none"/> </subsetattr> <importgroupsubsetattr groupsubsetname="planecolours"/> <subsetattr name="default" uppersubset="visiblesets"/> </groupsubsetattr> <groupsubsetattr groupsubsetname="FatCentreline2"> <importgroupsubsetattr groupsubsetname="baseBW4000"/> <importgroupsubsetattr groupsubsetname="baseSymbols4000"/> <subsetattr name="visiblesets" areamaskcolour="#7bffffff" areacolour="#664c4c4c" strokecolour="#ff000000" fontstyle="PLAIN" labelcolour="$labcolour"> <setvariable name="$labcolour" value="#ff000000"/> <linestylecol linestyle="centreline" strokewidth="20" strokecolour="$labcolour"/> <labelfcol labelstylename="centrelinelabel" fontname="Franklin Gothic Medium" fontstyle="ITALIC" size="50"/> </subsetattr> <importgroupsubsetattr groupsubsetname="planecolours"/> <subsetattr name="default" uppersubset="visiblesets"/> </groupsubsetattr> <groupsubsetattr groupsubsetname="baseBW25000"> <importgroupsubsetattr groupsubsetname="base"/> <subsetattr name="visiblesets" areamaskcolour="none" areacolour="#ff000000" strokecolour="#ff000000"> <labelfcol labelstylename="default" labelcolour="none"/> <linestylecol linestyle="centreline" strokewidth="30.0"/> <linestylecol linestyle="wall" strokewidth="7" /> <linestylecol linestyle="estwall" strokewidth="7"/> <linestylecol linestyle="pitchbound" strokecolour="none"/> <linestylecol linestyle="ceilingbound" strokecolour="none"/> <linestylecol linestyle="detail" strokecolour="none"/> <linestylecol linestyle="filled" strokecolour="none"/> </subsetattr> <subsetattr name="greyed" uppersubset="visiblesets" labelcolour="none" areacolour="#447c7c7c" strokecolour="#44000000"> <linestylecol linestyle="centreline" strokewidth="15.0"/> <linestylecol linestyle="wall" strokewidth="7" /> <linestylecol linestyle="estwall" strokewidth="7"/> </subsetattr> <subsetattr name="white" uppersubset="visiblesets" labelcolour="none" areamaskcolour="#ffffffff" areacolour="none" strokecolour="none"> <linestylecol linestyle="wall" strokewidth="7" shadowstrokewidth="14.0" shadowstrokecolour="#ffffffff"/> <linestylecol linestyle="estwall" strokewidth="7" shadowstrokewidth="14.0" shadowstrokecolour="#ffffffff"/> <linestylecol linestyle="centreline" strokecolour="none"/> </subsetattr> <subsetattr name="default" uppersubset="visiblesets"/> </groupsubsetattr> <groupsubsetattr groupsubsetname="baseA3page"> <grid_def xorig="0.0" yorig="0.0" maxgridlines="8"> <gridspacing gswidth="1.0" maxgridlines="13"/> <gridspacing gswidth="5.0"/> <gridspacing gswidth="10.0"/> <gridspacing gswidth="50.0"/> <gridspacing gswidth="100.0"/> <gridspacing gswidth="500.0"/> </grid_def> <subsetattr name="visiblesets" areamaskcolour="#7bffffff" areacolour="#66cce5e5" strokecolour="$labcolour" fontstyle="PLAIN" labelcolour="$labcolour"> <setvariable name="$labcolour" value="#ff011110"/> <labelfcol labelstylename="default"/> <labelfcol labelstylename="titlenum" fontname="Franklin Gothic Medium" size="60"/> <labelfcol labelstylename="titlename" fontname="Franklin Gothic Medium" fontstyle="BOLD" size="120"/> <labelfcol labelstylename="titlebigname" fontname="Franklin Gothic Medium" fontstyle="BOLD" size="200"/> <labelfcol labelstylename="titlearea" fontname="Franklin Gothic Medium" fontstyle="BOLD" size="40"/> <labelfcol labelstylename="titleentname" fontname="Times New Roman" fontstyle="BOLD" size="60"/> <labelfcol labelstylename="titleentpos" fontname="Times New Roman" size="60"/> <labelfcol labelstylename="titlestats" fontname="Times New Roman" fontstyle="BOLD" size="50"/> <labelfcol labelstylename="titledetails" fontname="Times New Roman" size="50"/> <labelfcol labelstylename="gridnum" fontname="Franklin Gothic Medium" size="40"/> </subsetattr> <subsetattr name="frametitles" areamaskcolour="#f0ffffff" areacolour="#30ff0000" strokecolour="#ff990000" fontstyle="PLAIN" labelcolour="#ff501010"> <labelfcol labelstylename="titlename" fontname="Times New Roman" fontstyle="PLAIN" size="120"/> <linestylecol linestyle="detail" strokewidth="2.000" strokecolour="#ff800020"/> <linestylecol linestyle="wall" strokewidth="4.000" strokecolour="#ff800020"/> <linestylecol linestyle="estwall" strokewidth="4.000" spikegap="30" gapleng="14" spikeheight="0.0" strokecolour="#ff800020"/> <labelfcol labelstylename="default"/> <labelfcol labelstylename="titlenum" fontname="Franklin Gothic Medium" size="60"/> <labelfcol labelstylename="titlename" fontname="Franklin Gothic Medium" fontstyle="BOLD" size="120"/> <labelfcol labelstylename="titlebigname" fontname="Franklin Gothic Medium" fontstyle="BOLD" size="200"/> <labelfcol labelstylename="titlearea" fontname="Franklin Gothic Medium" fontstyle="BOLD" size="40"/> <labelfcol labelstylename="titleentname" fontname="Times New Roman" fontstyle="BOLD" size="60"/> <labelfcol labelstylename="titleentpos" fontname="Times New Roman" size="60"/> <labelfcol labelstylename="titlestats" fontname="Times New Roman" fontstyle="BOLD" size="50"/> <labelfcol labelstylename="titledetails" fontname="Times New Roman" size="50"/> <labelfcol labelstylename="gridnum" fontname="Franklin Gothic Medium" size="40"/> </subsetattr> <subsetattr name="shaded" uppersubset="frametitles" areamaskcolour="none" areacolour="#223333a3"> </subsetattr> <subsetattr name="default" uppersubset="frametitles"/> <importgroupsubsetattr groupsubsetname="planecolours"/> </groupsubsetattr> <groupsubsetattr groupsubsetname="pockettopo"> <importgroupsubsetattr groupsubsetname="base250"/> <importgroupsubsetattr groupsubsetname="base"/> <importgroupsubsetattr groupsubsetname="baseSymbols250"/> <subsetattr name="visiblesets" areamaskcolour="#7bffffff" areacolour="#66cce5e5" strokecolour="$labcolour" fontstyle="PLAIN" labelcolour="$labcolour"> <setvariable name="$labcolour" value="#ff011110"/> <linestylecol linestyle="centreline" strokewidth="0.15" strokecolour="#ffc00000"/> <linestylecol linestyle="wall" strokewidth="0.65"/> <linestylecol linestyle="estwall" strokewidth="0.65" spikegap="2.5" gapleng="1.75" spikeheight="0.0" strokecolour="#ff000000"/> <linestylecol linestyle="pitchbound" strokewidth="0.31" spikegap="2.5" gapleng="0.0" spikeheight="2.5"/> <linestylecol linestyle="ceilingbound" strokewidth="0.31" spikegap="2.5" gapleng="1.5" spikeheight="1.5"/> <linestylecol linestyle="detail" strokewidth="0.31"/> <linestylecol linestyle="filled" strokewidth="0.0" strokecolour="#ff000080"/> </subsetattr> <importgroupsubsetattr groupsubsetname="planecolours"/> <subsetattr name="default" uppersubset="visiblesets"/> </groupsubsetattr> <groupsubsetattr groupsubsetname="tracedmap25000"> <importgroupsubsetattr groupsubsetname="base"/> <subsetattr name="visiblesets" areamaskcolour="none" areacolour="none" strokecolour="#ff000000"> <labelfcol labelstylename="default" labelcolour="none"/> <linestylecol linestyle="centreline" strokecolour="none"/> <linestylecol linestyle="wall" strokewidth="30.0" /> <linestylecol linestyle="estwall" strokewidth="15.0" spikegap="180" gapleng="80.0"/> <linestylecol linestyle="pitchbound" strokewidth="15" spikegap="140" gapleng="0.0" spikeheight="90"/> <linestylecol linestyle="ceilingbound" strokewidth="40" strokecolour="#ff4040ff"/> <linestylecol linestyle="detail" strokewidth="15"/> <linestylecol linestyle="filled" strokecolour="none"/> <symbolaut dname="puddle" symbolareafillcolour="#ff0000f0" buttonaction="overwrite" description="water area"> <asymbol name="puddle"/> </symbolaut> </subsetattr> <subsetattr name="default" uppersubset="visiblesets"/> </groupsubsetattr> </fontcolours> </tunnelxml> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/northarrowsmall.xml���������������������������������������������������0000755�0000000�0000000�00000002642�12066375447�016764� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:09"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="wall" splined="1"> <pt X="-30.0" Y="20.0"/> <pt X="-30.0" Y="10.0"/> </skpath> <skpath from="2" to="3" linestyle="wall" splined="1"> <pt X="-35.0" Y="-5.0"/> <pt X="-30.0" Y="-10.0"/> </skpath> <skpath from="4" to="3" linestyle="wall" splined="1"> <pt X="-25.0" Y="-5.0"/> <pt X="-30.0" Y="-10.0"/> </skpath> <skpath from="5" to="3" linestyle="centreline"> <pt X="-32.5" Y="-2.5"/> <pt X="-30.0" Y="-10.0"/> </skpath> <skpath from="1" to="3" linestyle="wall" splined="1"> <pt X="-30.0" Y="10.0"/> <pt X="-30.0" Y="-10.0"/> </skpath> <skpath from="1" to="6" linestyle="wall" splined="1"> <pt X="-30.0" Y="10.0"/> <pt X="-40.0" Y="10.0"/> </skpath> <skpath from="7" to="1" linestyle="wall" splined="1"> <pt X="-20.0" Y="10.0"/> <pt X="-30.0" Y="10.0"/> </skpath> <skpath from="3" to="3" linestyle="invisible"> <pt X="-30.0" Y="-10.0"/> <pt X="-18.969856" Y="-10.801405"/> <pt X="-19.16215" Y="21.79229"/> <pt X="-41.94889" Y="22.273024"/> <pt X="-41.564304" Y="-11.570578"/> <pt X="-30.0" Y="-10.0"/> </skpath> </sketch> </tunnelxml> ����������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/bats.xml��������������������������������������������������������������0000644�0000000�0000000�00000007434�12066375447�014460� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:08"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="centreline"> <pt X="2109.9624" Y="-324.8027"/> <pt X="2119.125" Y="-324.8027"/> </skpath> <skpath from="2" to="3" linestyle="detail" splined="1"> <pt X="2113.6008" Y="-327.8433"/> <pt X="2110.74" Y="-328.3481"/> <pt X="2108.384" Y="-329.48404"/> </skpath> <skpath from="3" to="4" linestyle="detail" splined="1"> <pt X="2108.384" Y="-329.48404"/> <pt X="2106.3225" Y="-328.8109"/> <pt X="2103.083" Y="-326.497"/> <pt X="2102.0312" Y="-324.77213"/> </skpath> <skpath from="4" to="5" linestyle="detail" splined="1"> <pt X="2102.0312" Y="-324.77213"/> <pt X="2104.3452" Y="-325.5294"/> <pt X="2105.9019" Y="-325.3611"/> <pt X="2106.7432" Y="-324.6459"/> <pt X="2107.206" Y="-323.88864"/> </skpath> <skpath from="5" to="6" linestyle="detail" splined="1"> <pt X="2107.206" Y="-323.88864"/> <pt X="2108.7205" Y="-324.85626"/> <pt X="2110.235" Y="-325.1928"/> <pt X="2112.0862" Y="-324.98245"/> <pt X="2113.5166" Y="-324.01483"/> </skpath> <skpath from="7" to="8" linestyle="detail" splined="1"> <pt X="2116.6719" Y="-327.88535"/> <pt X="2118.1443" Y="-327.88535"/> <pt X="2119.2383" Y="-328.22192"/> <pt X="2121.2998" Y="-329.1054"/> </skpath> <skpath from="8" to="9" linestyle="detail" splined="1"> <pt X="2121.2998" Y="-329.1054"/> <pt X="2123.782" Y="-328.60056"/> <pt X="2125.675" Y="-327.5067"/> <pt X="2126.853" Y="-326.2446"/> <pt X="2127.6523" Y="-325.02454"/> </skpath> <skpath from="9" to="10" linestyle="detail" splined="1"> <pt X="2127.6523" Y="-325.02454"/> <pt X="2125.4226" Y="-325.73975"/> <pt X="2124.0764" Y="-326.0763"/> <pt X="2122.8984" Y="-325.69766"/> <pt X="2121.2998" Y="-324.73004"/> </skpath> <skpath from="10" to="11" linestyle="detail" splined="1"> <pt X="2121.2998" Y="-324.73004"/> <pt X="2119.8694" Y="-325.27698"/> <pt X="2118.7334" Y="-325.27698"/> <pt X="2117.892" Y="-324.98245"/> <pt X="2116.84" Y="-324.26727"/> <pt X="2116.5457" Y="-323.88864"/> </skpath> <skpath from="2" to="6" linestyle="detail" splined="1"> <pt X="2113.6008" Y="-327.8433"/> <pt X="2112.9697" Y="-326.41287"/> <pt X="2112.9277" Y="-325.31903"/> <pt X="2113.5166" Y="-324.01483"/> </skpath> <skpath from="7" to="11" linestyle="detail" splined="1"> <pt X="2116.6719" Y="-327.88535"/> <pt X="2117.2188" Y="-326.70737"/> <pt X="2117.1768" Y="-325.69766"/> <pt X="2116.5457" Y="-323.88864"/> </skpath> <skpath from="2" to="7" linestyle="invisible" splined="1"> <pt X="2113.6008" Y="-327.8433"/> <pt X="2116.6719" Y="-327.88535"/> </skpath> <skpath from="6" to="11" linestyle="invisible" splined="1"> <pt X="2113.5166" Y="-324.01483"/> <pt X="2116.5457" Y="-323.88864"/> </skpath> <skpath from="2" to="2" linestyle="filled" splined="1"> <pt X="2113.6008" Y="-327.8433"/> <pt X="2113.9373" Y="-330.1151"/> <pt X="2114.4421" Y="-328.64264"/> <pt X="2115.7463" Y="-328.60056"/> <pt X="2116.3354" Y="-330.07303"/> <pt X="2116.7139" Y="-328.17984"/> <pt X="2117.0085" Y="-327.21222"/> <pt X="2117.2188" Y="-326.0763"/> <pt X="2117.0085" Y="-325.06662"/> <pt X="2116.7139" Y="-323.97278"/> <pt X="2115.9568" Y="-323.17343"/> <pt X="2115.3257" Y="-322.921"/> <pt X="2114.274" Y="-323.25757"/> <pt X="2113.6848" Y="-323.9307"/> <pt X="2112.9697" Y="-325.27698"/> <pt X="2113.0117" Y="-326.16046"/> <pt X="2113.18" Y="-326.74945"/> <pt X="2113.6008" Y="-327.8433"/> </skpath> </sketch> </tunnelxml> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/bigboulder2.xml�������������������������������������������������������0000755�0000000�0000000�00000002537�12066375447�015731� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:08"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="centreline"> <pt X="2100.846" Y="-316.27625"/> <pt X="2125.7039" Y="-332.0329"/> </skpath> <skpath from="2" to="2" linestyle="detail"> <pt X="2101.8843" Y="-332.91647"/> <pt X="2101.455" Y="-316.3972"/> <pt X="2115.4714" Y="-313.25067"/> <pt X="2125.9836" Y="-316.4687"/> <pt X="2125.2686" Y="-331.62927"/> <pt X="2113.3262" Y="-334.84732"/> <pt X="2101.8843" Y="-332.91647"/> </skpath> <skpath from="3" to="3" linestyle="invisible"> <pt X="2099.8818" Y="-334.41824"/> <pt X="2112.9685" Y="-337.27872"/> <pt X="2126.8418" Y="-332.91647"/> <pt X="2128.0576" Y="-315.68207"/> <pt X="2114.6133" Y="-311.31982"/> <pt X="2099.5242" Y="-315.53903"/> <pt X="2099.8818" Y="-334.41824"/> </skpath> <skpath from="3" to="2" linestyle="invisible" splined="1"> <pt X="2099.8818" Y="-334.41824"/> <pt X="2101.8843" Y="-332.91647"/> </skpath> <skpath from="0" to="2" linestyle="invisible"> <pt X="2100.846" Y="-316.27625"/> <pt X="2101.8843" Y="-332.91647"/> </skpath> </sketch> </tunnelxml> �����������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/column.xml������������������������������������������������������������0000644�0000000�0000000�00000002330�12066375447�015012� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:09"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="centreline" splined="1"> <pt X="30.0" Y="-180.0"/> <pt X="30.0" Y="-180.0"/> </skpath> <skpath from="2" to="0" linestyle="detail"> <pt X="27.131954" Y="-182.90779"/> <pt X="30.0" Y="-180.0"/> </skpath> <skpath from="3" to="0" linestyle="detail"> <pt X="32.585964" Y="-182.66211"/> <pt X="30.0" Y="-180.0"/> </skpath> <skpath from="4" to="0" linestyle="detail" splined="1"> <pt X="30.0" Y="-175.0"/> <pt X="30.0" Y="-180.0"/> </skpath> <skpath from="5" to="6" linestyle="centreline" splined="1"> <pt X="29.293903" Y="-179.17351"/> <pt X="30.866232" Y="-179.17351"/> </skpath> <skpath from="4" to="7" linestyle="detail" splined="1"> <pt X="30.0" Y="-175.0"/> <pt X="27.419798" Y="-172.47298"/> </skpath> <skpath from="4" to="8" linestyle="detail" splined="1"> <pt X="30.0" Y="-175.0"/> <pt X="32.701527" Y="-172.27242"/> </skpath> </sketch> </tunnelxml> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/popcorn.xml�����������������������������������������������������������0000644�0000000�0000000�00000004072�12066375447�015202� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:09"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="detail"> <pt X="2113.8079" Y="-328.2046"/> <pt X="2113.8997" Y="-324.4"/> </skpath> <skpath from="2" to="3" linestyle="detail"> <pt X="2117.3516" Y="-324.4"/> <pt X="2117.3516" Y="-328.23514"/> </skpath> <skpath from="4" to="5" linestyle="detail"> <pt X="2109.9946" Y="-328.1954"/> <pt X="2110.0093" Y="-324.4"/> </skpath> <skpath from="1" to="2" linestyle="detail"> <pt X="2113.8997" Y="-324.4"/> <pt X="2117.3516" Y="-324.4"/> </skpath> <skpath from="2" to="6" linestyle="detail"> <pt X="2117.3516" Y="-324.4"/> <pt X="2119.2031" Y="-324.4"/> </skpath> <skpath from="5" to="1" linestyle="detail"> <pt X="2110.0093" Y="-324.4"/> <pt X="2113.8997" Y="-324.4"/> </skpath> <skpath from="5" to="7" linestyle="detail"> <pt X="2110.0093" Y="-324.4"/> <pt X="2108.295" Y="-324.4"/> </skpath> <skpath from="8" to="9" linestyle="centreline"> <pt X="2113.906" Y="-322.1072"/> <pt X="2113.8281" Y="-324.80887"/> </skpath> <skpath from="4" to="4" linestyle="filled" splined="1"> <pt X="2109.9946" Y="-328.1954"/> <pt X="2109.0623" Y="-328.90094"/> <pt X="2109.9692" Y="-329.5813"/> <pt X="2110.8513" Y="-328.92615"/> <pt X="2109.9946" Y="-328.1954"/> </skpath> <skpath from="0" to="0" linestyle="filled" splined="1"> <pt X="2113.8079" Y="-328.2046"/> <pt X="2112.9426" Y="-328.82535"/> <pt X="2113.749" Y="-329.5057"/> <pt X="2114.7065" Y="-328.82535"/> <pt X="2113.8079" Y="-328.2046"/> </skpath> <skpath from="3" to="3" linestyle="filled" splined="1"> <pt X="2117.3516" Y="-328.23514"/> <pt X="2116.5222" Y="-328.84985"/> <pt X="2117.3674" Y="-329.54587"/> <pt X="2118.4114" Y="-328.75043"/> <pt X="2117.3516" Y="-328.23514"/> </skpath> </sketch> </tunnelxml> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/pebble2.xml�����������������������������������������������������������0000644�0000000�0000000�00000003473�12066375447�015041� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:09"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="detail" splined="1"> <pt X="2120.723" Y="-325.04794"/> <pt X="2120.7002" Y="-325.42615"/> <pt X="2120.3323" Y="-326.0133"/> <pt X="2119.7593" Y="-326.23605"/> <pt X="2119.2275" Y="-326.13782"/> <pt X="2118.8652" Y="-325.90027"/> <pt X="2118.6724" Y="-325.56018"/> <pt X="2118.6116" Y="-325.06934"/> </skpath> <skpath from="1" to="0" linestyle="detail" splined="1"> <pt X="2118.6116" Y="-325.06934"/> <pt X="2118.6401" Y="-324.71173"/> <pt X="2118.9978" Y="-324.22333"/> <pt X="2119.6917" Y="-323.8992"/> <pt X="2120.4385" Y="-324.26312"/> <pt X="2120.645" Y="-324.6644"/> <pt X="2120.723" Y="-325.04794"/> </skpath> <skpath from="2" to="3" linestyle="centreline"> <pt X="2118.9404" Y="-325.3159"/> <pt X="2120.9744" Y="-325.35696"/> </skpath> <skpath from="4" to="0" linestyle="invisible" splined="1"> <pt X="2122.5574" Y="-324.75842"/> <pt X="2120.723" Y="-325.04794"/> </skpath> <skpath from="4" to="4" linestyle="invisible" splined="1"> <pt X="2122.5574" Y="-324.75842"/> <pt X="2122.0823" Y="-326.71115"/> <pt X="2120.13" Y="-328.1788"/> <pt X="2117.9346" Y="-327.47058"/> <pt X="2117.0337" Y="-326.10123"/> <pt X="2116.8657" Y="-325.37396"/> <pt X="2116.875" Y="-325.16132"/> <pt X="2117.3015" Y="-323.677"/> <pt X="2118.3484" Y="-322.5452"/> <pt X="2120.56" Y="-322.10318"/> <pt X="2121.6492" Y="-322.99277"/> <pt X="2122.1426" Y="-323.855"/> <pt X="2122.5574" Y="-324.75842"/> </skpath> </sketch> </tunnelxml> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/snow.xml��������������������������������������������������������������0000755�0000000�0000000�00000003354�12066375447�014515� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:09"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="centreline"> <pt X="2110.0" Y="-320.0"/> <pt X="2110.0" Y="-330.0"/> </skpath> <skpath from="2" to="3" linestyle="detail"> <pt X="2107.5" Y="-325.0"/> <pt X="2107.5" Y="-330.0"/> </skpath> <skpath from="4" to="5" linestyle="detail"> <pt X="2110.0" Y="-327.5"/> <pt X="2115.0" Y="-327.5"/> </skpath> <skpath from="6" to="7" linestyle="detail"> <pt X="2112.5" Y="-320.0"/> <pt X="2112.5" Y="-325.0"/> </skpath> <skpath from="8" to="9" linestyle="detail"> <pt X="2105.0" Y="-322.5"/> <pt X="2110.0" Y="-322.5"/> </skpath> <skpath from="8" to="0" linestyle="invisible"> <pt X="2105.0" Y="-322.5"/> <pt X="2105.0" Y="-320.0"/> <pt X="2110.0" Y="-320.0"/> </skpath> <skpath from="0" to="6" linestyle="invisible"> <pt X="2110.0" Y="-320.0"/> <pt X="2112.5" Y="-320.0"/> </skpath> <skpath from="6" to="5" linestyle="invisible"> <pt X="2112.5" Y="-320.0"/> <pt X="2115.0" Y="-320.0"/> <pt X="2115.0" Y="-327.5"/> </skpath> <skpath from="5" to="1" linestyle="invisible"> <pt X="2115.0" Y="-327.5"/> <pt X="2115.0" Y="-330.0"/> <pt X="2110.0" Y="-330.0"/> </skpath> <skpath from="1" to="3" linestyle="invisible"> <pt X="2110.0" Y="-330.0"/> <pt X="2107.5" Y="-330.0"/> </skpath> <skpath from="3" to="8" linestyle="invisible"> <pt X="2107.5" Y="-330.0"/> <pt X="2105.0" Y="-330.0"/> <pt X="2105.0" Y="-322.5"/> </skpath> </sketch> </tunnelxml> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/pants.xml�������������������������������������������������������������0000644�0000000�0000000�00000013136�12066375447�014650� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:09"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="detail" splined="1"> <pt X="2109.1274" Y="-328.9457"/> <pt X="2110.691" Y="-328.56287"/> <pt X="2111.7756" Y="-328.53094"/> <pt X="2113.1477" Y="-328.56287"/> </skpath> <skpath from="2" to="3" linestyle="detail" splined="1"> <pt X="2113.6582" Y="-328.62668"/> <pt X="2114.5195" Y="-328.75427"/> <pt X="2115.2854" Y="-328.85"/> <pt X="2116.4978" Y="-329.13715"/> <pt X="2117.2317" Y="-329.61572"/> </skpath> <skpath from="4" to="5" linestyle="detail" splined="1"> <pt X="2109.319" Y="-329.2967"/> <pt X="2110.3718" Y="-328.9457"/> <pt X="2111.5842" Y="-328.85"/> <pt X="2112.6372" Y="-328.91382"/> <pt X="2114.041" Y="-328.91382"/> <pt X="2115.2214" Y="-329.16907"/> <pt X="2116.402" Y="-329.48813"/> <pt X="2117.0083" Y="-329.87097"/> </skpath> <skpath from="1" to="6" linestyle="detail" splined="1"> <pt X="2113.1477" Y="-328.56287"/> <pt X="2113.2114" Y="-327.6376"/> <pt X="2113.2754" Y="-326.83994"/> </skpath> <skpath from="2" to="7" linestyle="detail" splined="1"> <pt X="2113.6582" Y="-328.62668"/> <pt X="2113.6582" Y="-327.92474"/> <pt X="2113.754" Y="-327.44617"/> <pt X="2113.8176" Y="-326.71234"/> </skpath> <skpath from="6" to="8" linestyle="detail" splined="1"> <pt X="2113.2754" Y="-326.83994"/> <pt X="2112.8286" Y="-326.0104"/> <pt X="2112.3818" Y="-325.24466"/> <pt X="2111.68" Y="-324.63846"/> </skpath> <skpath from="9" to="10" linestyle="detail" splined="1"> <pt X="2111.8713" Y="-324.3194"/> <pt X="2112.701" Y="-325.02133"/> <pt X="2113.1794" Y="-325.81897"/> <pt X="2113.5305" Y="-326.4571"/> </skpath> <skpath from="7" to="11" linestyle="detail" splined="1"> <pt X="2113.8176" Y="-326.71234"/> <pt X="2115.062" Y="-325.4042"/> <pt X="2115.5088" Y="-324.86182"/> <pt X="2115.764" Y="-324.63846"/> </skpath> <skpath from="10" to="12" linestyle="detail" splined="1"> <pt X="2113.5305" Y="-326.4571"/> <pt X="2114.1367" Y="-325.75516"/> <pt X="2114.711" Y="-325.11703"/> <pt X="2115.1257" Y="-324.63846"/> <pt X="2115.4768" Y="-324.06415"/> </skpath> <skpath from="11" to="12" linestyle="detail" splined="1"> <pt X="2115.764" Y="-324.63846"/> <pt X="2115.4768" Y="-324.06415"/> </skpath> <skpath from="8" to="9" linestyle="detail" splined="1"> <pt X="2111.68" Y="-324.63846"/> <pt X="2111.8713" Y="-324.3194"/> </skpath> <skpath from="0" to="4" linestyle="detail" splined="1"> <pt X="2109.1274" Y="-328.9457"/> <pt X="2109.319" Y="-329.2967"/> </skpath> <skpath from="5" to="3" linestyle="detail" splined="1"> <pt X="2117.0083" Y="-329.87097"/> <pt X="2117.2317" Y="-329.61572"/> </skpath> <skpath from="9" to="12" linestyle="detail" splined="1"> <pt X="2111.8713" Y="-324.3194"/> <pt X="2112.2861" Y="-323.90463"/> <pt X="2112.9563" Y="-323.90463"/> <pt X="2113.2434" Y="-323.777"/> <pt X="2113.6262" Y="-323.74512"/> <pt X="2113.9773" Y="-323.777"/> <pt X="2114.2644" Y="-323.80893"/> <pt X="2114.5835" Y="-323.6175"/> <pt X="2114.743" Y="-323.6175"/> <pt X="2114.9663" Y="-323.7132"/> <pt X="2115.4768" Y="-324.06415"/> </skpath> <skpath from="11" to="13" linestyle="detail" splined="1"> <pt X="2115.764" Y="-324.63846"/> <pt X="2116.083" Y="-325.62753"/> <pt X="2116.5295" Y="-326.0104"/> <pt X="2117.1677" Y="-326.4571"/> </skpath> <skpath from="13" to="3" linestyle="detail" splined="1"> <pt X="2117.1677" Y="-326.4571"/> <pt X="2117.104" Y="-326.64853"/> <pt X="2117.1357" Y="-326.83994"/> <pt X="2117.391" Y="-327.28662"/> <pt X="2117.423" Y="-327.60568"/> <pt X="2117.423" Y="-327.95663"/> <pt X="2117.1997" Y="-328.59476"/> <pt X="2117.1677" Y="-328.8819"/> <pt X="2117.2317" Y="-329.61572"/> </skpath> <skpath from="13" to="11" linestyle="detail" splined="1"> <pt X="2117.1677" Y="-326.4571"/> <pt X="2117.2317" Y="-326.23373"/> <pt X="2117.0083" Y="-326.07422"/> <pt X="2116.4338" Y="-325.65945"/> <pt X="2116.1467" Y="-325.3404"/> <pt X="2115.9873" Y="-324.8937"/> <pt X="2115.764" Y="-324.63846"/> </skpath> <skpath from="0" to="14" linestyle="detail" splined="1"> <pt X="2109.1274" Y="-328.9457"/> <pt X="2109.0" Y="-328.18"/> <pt X="2109.0" Y="-327.70142"/> <pt X="2109.287" Y="-327.50998"/> <pt X="2109.287" Y="-327.1271"/> <pt X="2109.1594" Y="-326.83994"/> <pt X="2109.0957" Y="-326.5209"/> <pt X="2109.0637" Y="-325.9785"/> </skpath> <skpath from="14" to="15" linestyle="detail" splined="1"> <pt X="2109.0637" Y="-325.9785"/> <pt X="2109.0317" Y="-325.78708"/> </skpath> <skpath from="14" to="8" linestyle="detail" splined="1"> <pt X="2109.0637" Y="-325.9785"/> <pt X="2109.8933" Y="-325.59564"/> <pt X="2110.8186" Y="-325.37228"/> <pt X="2111.2014" Y="-325.02133"/> <pt X="2111.68" Y="-324.63846"/> </skpath> <skpath from="15" to="8" linestyle="detail" splined="1"> <pt X="2109.0317" Y="-325.78708"/> <pt X="2109.4465" Y="-325.53183"/> <pt X="2110.0847" Y="-325.3404"/> <pt X="2110.8503" Y="-325.02133"/> <pt X="2111.0737" Y="-324.9256"/> <pt X="2111.297" Y="-324.63846"/> <pt X="2111.68" Y="-324.63846"/> </skpath> <skpath from="16" to="17" linestyle="centreline"> <pt X="2109.434" Y="-326.24826"/> <pt X="2116.266" Y="-325.3265"/> </skpath> </sketch> </tunnelxml> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/rats.xml��������������������������������������������������������������0000644�0000000�0000000�00000013214�12066375447�014471� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:09"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="detail" splined="1"> <pt X="2110.1523" Y="-325.62155"/> <pt X="2110.3801" Y="-327.0258"/> <pt X="2111.0632" Y="-328.31616"/> <pt X="2111.7463" Y="-328.80954"/> <pt X="2113.4922" Y="-329.03726"/> <pt X="2115.8074" Y="-328.88544"/> <pt X="2116.4905" Y="-328.6577"/> <pt X="2117.1357" Y="-328.24026"/> <pt X="2117.743" Y="-327.59506"/> <pt X="2118.3882" Y="-326.87396"/> <pt X="2118.6157" Y="-326.57034"/> <pt X="2118.8816" Y="-326.45648"/> <pt X="2119.576" Y="-326.28687"/> </skpath> <skpath from="2" to="3" linestyle="detail" splined="1"> <pt X="2120.3528" Y="-326.052"/> <pt X="2120.7412" Y="-325.84924"/> <pt X="2121.0828" Y="-325.54562"/> <pt X="2121.69" Y="-325.12817"/> </skpath> <skpath from="1" to="2" linestyle="detail" splined="1"> <pt X="2119.576" Y="-326.28687"/> <pt X="2119.6025" Y="-327.0258"/> <pt X="2119.944" Y="-327.13965"/> <pt X="2120.3997" Y="-326.87396"/> <pt X="2120.3528" Y="-326.052"/> </skpath> <skpath from="1" to="4" linestyle="detail" splined="1"> <pt X="2119.576" Y="-326.28687"/> <pt X="2119.4888" Y="-325.7354"/> </skpath> <skpath from="2" to="5" linestyle="detail" splined="1"> <pt X="2120.3528" Y="-326.052"/> <pt X="2120.1719" Y="-325.54562"/> </skpath> <skpath from="5" to="6" linestyle="invisible" splined="1"> <pt X="2120.1719" Y="-325.54562"/> <pt X="2120.5134" Y="-325.4318"/> </skpath> <skpath from="6" to="6" linestyle="filled" splined="1"> <pt X="2120.5134" Y="-325.4318"/> <pt X="2120.6653" Y="-325.54562"/> <pt X="2120.7412" Y="-325.35587"/> <pt X="2120.5894" Y="-325.27997"/> <pt X="2120.5134" Y="-325.4318"/> </skpath> <skpath from="3" to="7" linestyle="detail" splined="1"> <pt X="2121.69" Y="-325.12817"/> <pt X="2121.614" Y="-324.93842"/> <pt X="2120.9688" Y="-324.93842"/> <pt X="2120.2097" Y="-324.93842"/> <pt X="2119.2231" Y="-324.93842"/> <pt X="2118.1604" Y="-325.0143"/> </skpath> <skpath from="7" to="8" linestyle="detail" splined="1"> <pt X="2118.1604" Y="-325.0143"/> <pt X="2118.6157" Y="-324.74863"/> </skpath> <skpath from="9" to="8" linestyle="detail"> <pt X="2118.5398" Y="-324.48297"/> <pt X="2118.9194" Y="-324.52094"/> <pt X="2118.7297" Y="-324.6348"/> <pt X="2118.9573" Y="-324.6348"/> <pt X="2118.7676" Y="-324.7107"/> <pt X="2119.0332" Y="-324.7866"/> <pt X="2118.6157" Y="-324.74863"/> </skpath> <skpath from="10" to="11" linestyle="detail"> <pt X="2113.2644" Y="-324.40707"/> <pt X="2113.4163" Y="-324.33118"/> <pt X="2113.1887" Y="-324.33118"/> <pt X="2113.3784" Y="-324.2932"/> <pt X="2113.0747" Y="-324.2932"/> <pt X="2113.2644" Y="-324.25525"/> <pt X="2112.961" Y="-324.21732"/> </skpath> <skpath from="11" to="12" linestyle="detail" splined="1"> <pt X="2112.961" Y="-324.21732"/> <pt X="2111.6704" Y="-324.55887"/> <pt X="2110.7217" Y="-324.8625"/> <pt X="2110.1904" Y="-325.0902"/> </skpath> <skpath from="13" to="14" linestyle="detail" splined="1"> <pt X="2113.4163" Y="-326.79807"/> <pt X="2113.7578" Y="-326.26672"/> <pt X="2113.5303" Y="-325.5077"/> <pt X="2112.7712" Y="-325.20407"/> <pt X="2112.5967" Y="-325.08466"/> </skpath> <skpath from="14" to="10" linestyle="detail" splined="1"> <pt X="2112.5967" Y="-325.08466"/> <pt X="2112.3157" Y="-324.7107"/> <pt X="2112.961" Y="-324.52094"/> <pt X="2113.2644" Y="-324.40707"/> </skpath> <skpath from="15" to="16" linestyle="detail" splined="1"> <pt X="2117.591" Y="-325.242"/> <pt X="2117.667" Y="-324.74863"/> </skpath> <skpath from="16" to="9" linestyle="detail" splined="1"> <pt X="2117.667" Y="-324.74863"/> <pt X="2118.1982" Y="-324.48297"/> <pt X="2118.5398" Y="-324.48297"/> </skpath> <skpath from="16" to="14" linestyle="detail" splined="1"> <pt X="2117.667" Y="-324.74863"/> <pt X="2117.2495" Y="-324.67273"/> <pt X="2115.9211" Y="-324.59683"/> <pt X="2115.0103" Y="-324.59683"/> <pt X="2114.0994" Y="-324.6348"/> <pt X="2112.8472" Y="-324.74863"/> <pt X="2112.5967" Y="-325.08466"/> </skpath> <skpath from="0" to="17" linestyle="detail" splined="1"> <pt X="2110.1523" Y="-325.62155"/> <pt X="2108.9" Y="-325.31793"/> <pt X="2107.6096" Y="-325.31793"/> <pt X="2107.0403" Y="-325.4318"/> <pt X="2107.0403" Y="-325.69745"/> <pt X="2107.5718" Y="-325.84924"/> <pt X="2107.6475" Y="-325.8872"/> <pt X="2107.9133" Y="-325.8872"/> <pt X="2108.255" Y="-325.84924"/> <pt X="2108.7102" Y="-325.7354"/> <pt X="2109.014" Y="-325.7354"/> <pt X="2109.1277" Y="-325.7354"/> <pt X="2109.3933" Y="-325.8113"/> </skpath> <skpath from="17" to="12" linestyle="detail" splined="1"> <pt X="2109.3933" Y="-325.8113"/> <pt X="2109.2036" Y="-325.92517"/> <pt X="2108.7102" Y="-325.9631"/> <pt X="2108.179" Y="-326.07697"/> <pt X="2107.4958" Y="-326.07697"/> <pt X="2106.9644" Y="-326.03903"/> <pt X="2106.6987" Y="-325.62155"/> <pt X="2106.661" Y="-325.20407"/> <pt X="2107.306" Y="-324.97635"/> <pt X="2108.065" Y="-324.97635"/> <pt X="2108.6343" Y="-324.93842"/> <pt X="2109.2795" Y="-324.97635"/> <pt X="2109.8489" Y="-325.05225"/> <pt X="2110.1904" Y="-325.0902"/> </skpath> <skpath from="18" to="19" linestyle="centreline"> <pt X="2106.7766" Y="-325.61746"/> <pt X="2120.7217" Y="-325.3178"/> </skpath> </sketch> </tunnelxml> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/sand.xml��������������������������������������������������������������0000644�0000000�0000000�00000001747�12066375447�014455� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:09"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="centreline"> <pt X="2112.488" Y="-324.15903"/> <pt X="2116.1272" Y="-324.10452"/> </skpath> <skpath from="2" to="3" linestyle="detail"> <pt X="2114.6077" Y="-324.3672"/> <pt X="2114.7134" Y="-324.1986"/> </skpath> <skpath from="2" to="4" linestyle="invisible"> <pt X="2114.6077" Y="-324.3672"/> <pt X="2115.7332" Y="-325.36154"/> </skpath> <skpath from="4" to="4" linestyle="invisible"> <pt X="2115.7332" Y="-325.36154"/> <pt X="2114.4387" Y="-325.75552"/> <pt X="2113.6694" Y="-324.17957"/> <pt X="2114.9077" Y="-323.11017"/> <pt X="2115.6582" Y="-324.0107"/> <pt X="2115.7332" Y="-325.36154"/> </skpath> </sketch> </tunnelxml> �������������������������tunnelx-20140102.orig/symbols/puddle.xml������������������������������������������������������������0000755�0000000�0000000�00000002100�12066375447�014770� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:09"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="detail"> <pt X="-80.0" Y="-25.0"/> <pt X="-85.0" Y="-20.0"/> </skpath> <skpath from="2" to="3" linestyle="centreline"> <pt X="-82.5" Y="-20.0"/> <pt X="-82.5" Y="-25.0"/> </skpath> <skpath from="0" to="3" linestyle="invisible"> <pt X="-80.0" Y="-25.0"/> <pt X="-82.5" Y="-25.0"/> </skpath> <skpath from="1" to="3" linestyle="invisible"> <pt X="-85.0" Y="-20.0"/> <pt X="-85.0" Y="-25.0"/> <pt X="-82.5" Y="-25.0"/> </skpath> <skpath from="1" to="2" linestyle="invisible" splined="1"> <pt X="-85.0" Y="-20.0"/> <pt X="-82.5" Y="-20.0"/> </skpath> <skpath from="0" to="2" linestyle="invisible"> <pt X="-80.0" Y="-25.0"/> <pt X="-80.0" Y="-20.0"/> <pt X="-82.5" Y="-20.0"/> </skpath> </sketch> </tunnelxml> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/straws.xml������������������������������������������������������������0000644�0000000�0000000�00000003666�12066375447�015055� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:09"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="centreline" splined="1"> <pt X="29.293903" Y="-179.17351"/> <pt X="30.866232" Y="-179.17351"/> </skpath> <skpath from="2" to="3" linestyle="detail"> <pt X="28.25667" Y="-182.37373"/> <pt X="29.873055" Y="-182.37373"/> </skpath> <skpath from="3" to="4" linestyle="detail"> <pt X="29.873055" Y="-182.37373"/> <pt X="31.489439" Y="-182.37373"/> </skpath> <skpath from="4" to="5" linestyle="detail"> <pt X="31.489439" Y="-182.37373"/> <pt X="32.99661" Y="-182.37373"/> </skpath> <skpath from="5" to="6" linestyle="detail"> <pt X="32.99661" Y="-182.37373"/> <pt X="34.15429" Y="-182.37373"/> </skpath> <skpath from="7" to="2" linestyle="detail"> <pt X="26.727657" Y="-182.37373"/> <pt X="28.25667" Y="-182.37373"/> </skpath> <skpath from="7" to="8" linestyle="detail"> <pt X="26.727657" Y="-182.37373"/> <pt X="25.591818" Y="-182.37373"/> </skpath> <skpath from="7" to="9" linestyle="detail"> <pt X="26.727657" Y="-182.37373"/> <pt X="26.727657" Y="-178.44199"/> </skpath> <skpath from="2" to="10" linestyle="detail" splined="1"> <pt X="28.25667" Y="-182.37373"/> <pt X="28.278513" Y="-180.56076"/> </skpath> <skpath from="3" to="11" linestyle="detail" splined="1"> <pt X="29.873055" Y="-182.37373"/> <pt X="29.829369" Y="-177.21877"/> </skpath> <skpath from="5" to="12" linestyle="detail" splined="1"> <pt X="32.99661" Y="-182.37373"/> <pt X="32.99661" Y="-179.07542"/> </skpath> <skpath from="4" to="13" linestyle="detail" splined="1"> <pt X="31.489439" Y="-182.37373"/> <pt X="31.467596" Y="-178.07065"/> </skpath> </sketch> </tunnelxml> ��������������������������������������������������������������������������tunnelx-20140102.orig/symbols/fontcolours.xml�������������������������������������������������������0000644�0000000�0000000�00000011101�12261213471�016047� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml> <fontcolours fontstyle="PLAIN" fontname="Serif"> <image_file_directory name=""/> <image_file_directory name="rawscans"/> <image_file_directory name="expoimages/"/> <!-- You can put comments in this file like this --> <area_signal_def asigname="plan" asigeffect="keeparea"/> <area_signal_def asigname="rock" asigeffect="killarea"/> <area_signal_def asigname="hole" asigeffect="outlinearea"/> <area_signal_def asigname="verysteep" asigeffect="keeparea"/> <area_signal_def asigname="dropdown" asigeffect="hcoincide"/> <area_signal_def asigname="zsetrelative" asigeffect="zsetrelative"/> <area_signal_def asigname="frame" asigeffect="sketchframe"/> <area_signal_def asigname="elev" asigeffect="elevationpath"/> <survex_executable_directory name="C:\\Program files\\Survex\\"/> <survex_executable_directory name="C:\\Program files (x86)\\Survex\\"/> <survex_executable_directory name="/usr/bin/"/> <directory application="inkscape" name="C:\\Program files (x86)\\Inkscape\\"/> <groupsubsetattr groupsubsetname="base" groupsubsetselectable="no"> <grid_def xorig="0.0" yorig="0.0" maxgridlines="8"> <gridspacing gswidth="1.0" maxgridlines="13"/> <gridspacing gswidth="5.0"/> <gridspacing gswidth="10.0"/> <gridspacing gswidth="50.0"/> <gridspacing gswidth="100.0"/> <gridspacing gswidth="500.0"/> </grid_def> <subsetattr name="default"/> <subsetattr name="todelete"/> <subsetattr name="obscuredsets" areamaskcolour="none" areacolour="none" labelcolour="none" strokecolour="none" fontstyle="PLAIN" size="1" strokewidth="0.1"> <labelfcol labelstylename="default"/> <labelfcol labelstylename="qm"/> <labelfcol labelstylename="step"/> <labelfcol labelstylename="passage"/> <labelfcol labelstylename="area"/> <labelfcol labelstylename="entrance"/> <labelfcol labelstylename="cave"/> <labelfcol labelstylename="survey"/> <linestylecol linestyle="centreline"/> <linestylecol linestyle="wall"/> <linestylecol linestyle="estwall"/> <linestylecol linestyle="pitchbound"/> <linestylecol linestyle="ceilingbound"/> <linestylecol linestyle="detail"/> <linestylecol linestyle="filled" strokewidth="0.0"/> </subsetattr> </groupsubsetattr> <groupsubsetattr groupsubsetname="default" groupsubsetselectable="no"> <importgroupsubsetattr groupsubsetname="base"/> </groupsubsetattr> <groupsubsetattr groupsubsetname="planecolours" groupsubsetselectable="no"> <subsetattr name="red" uppersubset="visiblesets" areacolour="#88e53344"> <setvariable name="$labcolour" value="#ffb50023"/> </subsetattr> <subsetattr name="orange" uppersubset="visiblesets" areacolour="#88ff9900"> <setvariable name="$labcolour" value="#ffff9900"/> </subsetattr> <subsetattr name="yellow" uppersubset="visiblesets" areacolour="#88bbde00"> <setvariable name="$labcolour" value="#ff9bae00"/> </subsetattr> <subsetattr name="cyan" uppersubset="visiblesets" areacolour="#8850ffff"> <setvariable name="$labcolour" value="#ff00aaaa"/> </subsetattr> <subsetattr name="green" uppersubset="visiblesets" areacolour="#8829ff3d"> <setvariable name="$labcolour" value="#ff09bf1d"/> </subsetattr> <subsetattr name="blue" uppersubset="visiblesets" areacolour="#885555ff"> <setvariable name="$labcolour" value="#ff0033ff"/> </subsetattr> <subsetattr name="purple" uppersubset="visiblesets" areacolour="#88a900e5"> <setvariable name="$labcolour" value="#ffa900e5"/> </subsetattr> <subsetattr name="magenta" uppersubset="visiblesets" areacolour="#88ff00ff"> <setvariable name="$labcolour" value="#ffcc00cc"/> </subsetattr> <subsetattr name="green2" uppersubset="visiblesets" areacolour="#8819ff2d"> <setvariable name="$labcolour" value="#ff19ff2d"/> </subsetattr> <subsetattr name="blue2" uppersubset="visiblesets" areacolour="#880033ff"> <setvariable name="$labcolour" value="#ff0033ff"/> </subsetattr> <subsetattr name="purple2" uppersubset="visiblesets" areacolour="#88a900e5"> <setvariable name="$labcolour" value="#ffa900e5"/> </subsetattr> <subsetattr name="red2" uppersubset="visiblesets" areacolour="#88e50033"> <setvariable name="$labcolour" value="#ffe50033"/> </subsetattr> <subsetattr name="yellow2" uppersubset="visiblesets" areacolour="#88ccff00"> <setvariable name="$labcolour" value="#ffbbee00"/> </subsetattr> <subsetattr name="strongrey" uppersubset="visiblesets" areacolour="#88808080"> <setvariable name="$labcolour" value="#ff707070"/> </subsetattr> <subsetattr name="brightgrey" uppersubset="visiblesets" areacolour="#88ffffff"> <setvariable name="$labcolour" value="#ff606060"/> </subsetattr> </groupsubsetattr> </fontcolours> </tunnelxml> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/mud.xml���������������������������������������������������������������0000644�0000000�0000000�00000001713�12066375447�014306� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:09"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="detail"> <pt X="2112.043" Y="-323.91577"/> <pt X="2118.4758" Y="-323.94037"/> </skpath> <skpath from="2" to="3" linestyle="centreline"> <pt X="2112.488" Y="-324.15903"/> <pt X="2120.4258" Y="-324.07965"/> </skpath> <skpath from="0" to="4" linestyle="invisible" splined="1"> <pt X="2112.043" Y="-323.91577"/> <pt X="2110.858" Y="-325.61145"/> </skpath> <skpath from="4" to="4" linestyle="invisible"> <pt X="2110.858" Y="-325.61145"/> <pt X="2119.6555" Y="-325.61145"/> <pt X="2120.4438" Y="-322.30048"/> <pt X="2111.0786" Y="-322.6158"/> <pt X="2110.858" Y="-325.61145"/> </skpath> </sketch> </tunnelxml> �����������������������������������������������������tunnelx-20140102.orig/symbols/bedrock.xml�����������������������������������������������������������0000644�0000000�0000000�00000002237�12066375447�015134� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:08"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="centreline" splined="1"> <pt X="29.293903" Y="-179.17351"/> <pt X="30.866232" Y="-179.17351"/> </skpath> <skpath from="2" to="3" linestyle="detail" splined="1"> <pt X="27.462877" Y="-179.41272"/> <pt X="30.027311" Y="-179.41272"/> </skpath> <skpath from="3" to="4" linestyle="detail" splined="1"> <pt X="30.027311" Y="-179.41272"/> <pt X="29.989876" Y="-181.80869"/> </skpath> <skpath from="3" to="5" linestyle="detail" splined="1"> <pt X="30.027311" Y="-179.41272"/> <pt X="33.04099" Y="-179.43144"/> </skpath> <skpath from="5" to="6" linestyle="detail" splined="1"> <pt X="33.04099" Y="-179.43144"/> <pt X="33.059708" Y="-177.33496"/> </skpath> <skpath from="5" to="7" linestyle="detail" splined="1"> <pt X="33.04099" Y="-179.43144"/> <pt X="34.987713" Y="-179.43144"/> </skpath> </sketch> </tunnelxml> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/pebble.xml������������������������������������������������������������0000644�0000000�0000000�00000003370�12066375447�014753� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:09"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="detail" splined="1"> <pt X="2120.723" Y="-325.04794"/> <pt X="2120.7002" Y="-325.42615"/> <pt X="2120.3323" Y="-326.0133"/> <pt X="2119.7593" Y="-326.23605"/> <pt X="2119.2275" Y="-326.13782"/> <pt X="2118.8652" Y="-325.90027"/> <pt X="2118.6724" Y="-325.56018"/> <pt X="2118.6116" Y="-325.06934"/> </skpath> <skpath from="1" to="0" linestyle="detail" splined="1"> <pt X="2118.6116" Y="-325.06934"/> <pt X="2118.6401" Y="-324.71173"/> <pt X="2118.9978" Y="-324.22333"/> <pt X="2119.6917" Y="-323.8992"/> <pt X="2120.4385" Y="-324.26312"/> <pt X="2120.645" Y="-324.6644"/> <pt X="2120.723" Y="-325.04794"/> </skpath> <skpath from="2" to="0" linestyle="invisible" splined="1"> <pt X="2121.1797" Y="-324.98715"/> <pt X="2120.723" Y="-325.04794"/> </skpath> <skpath from="2" to="2" linestyle="invisible" splined="1"> <pt X="2121.1797" Y="-324.98715"/> <pt X="2120.9126" Y="-325.99387"/> <pt X="2119.8855" Y="-326.73352"/> <pt X="2118.7554" Y="-326.34314"/> <pt X="2118.3035" Y="-325.62405"/> <pt X="2118.4678" Y="-324.37082"/> <pt X="2119.0225" Y="-323.79553"/> <pt X="2120.173" Y="-323.5901"/> <pt X="2120.7278" Y="-324.06262"/> <pt X="2120.9744" Y="-324.51462"/> <pt X="2121.1797" Y="-324.98715"/> </skpath> <skpath from="3" to="4" linestyle="centreline"> <pt X="2118.9404" Y="-325.3159"/> <pt X="2120.9744" Y="-325.35696"/> </skpath> </sketch> </tunnelxml> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/fontcolours_a.xml�����������������������������������������������������0000644�0000000�0000000�00000052571�12261213471�016367� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml> <fontcolours fontstyle="PLAIN" fontname="Serif"> <groupsubsetattr groupsubsetname="baseSymbols250" groupsubsetselectable="no"> <subsetattr name="default"/> <subsetattr name="visiblesets"> <set multiplicity="1" buttonaction="overwrite" area-interaction="allowed-outside" position="endpath" scale="fixed" orientation="fixed"> <symbolaut dname="breeze" buttonaction="nobutton" description="breeze symbol"> <asymbol name="breeze" picscale="0.5" orientation="alongaxis"/> </symbolaut> <symbolaut dname="breeze_a" description="breeze symbol along direction"> <asymbol name="breeze" picscale="-0.5" orientation="alongaxis"/> </symbolaut> <symbolaut dname="slope" description="slope symbol"> <asymbol name="slope" picscale="0.5" orientation="alongaxis" drawstyle="filled"/> </symbolaut> <symbolaut dname="slope2" description="big slope symbol"> <asymbol name="slope" picscale="1.0" orientation="alongaxis" drawstyle="filled"/> </symbolaut> <symbolaut dname="stream" description="stream symbol"> <asymbol name="stream" picscale="0.5" orientation="nearaxis"/> </symbolaut> <symbolaut dname="stream2" description="big stream symbol"> <asymbol name="stream" picscale="1.2" orientation="nearaxis"/> </symbolaut> <symbolaut dname="bedrock" description="bare solid bedrock"> <asymbol name="bedrock"/> </symbolaut> <symbolaut dname="column" description="Stal column"> <asymbol name="column"/> </symbolaut> <symbolaut dname="curtain" description="Stal curtain"> <asymbol name="curtain"/> </symbolaut> <symbolaut dname="popcorn" description="popcorn formations"> <asymbol name="popcorn"/> </symbolaut> <symbolaut dname="stalactite" description="Stalactite"> <asymbol name="stalactite"/> </symbolaut> <symbolaut dname="stalagtite" buttonaction="nobutton" description="Misspelled stalactite"> <asymbol name="stalactite" picscale="40.0"/> </symbolaut> <symbolaut dname="stalagmite" description="Stalagmite"> <asymbol name="stalagmite"/> </symbolaut> <symbolaut dname="straws" description="Straws"> <asymbol name="straws"/> </symbolaut> <symbolaut dname="rats" buttonaction="nobutton" description="rat activity"> <asymbol name="rats"/> </symbolaut> <symbolaut dname="guano" description="bat shit"> <asymbol name="bats"/> </symbolaut> <symbolaut dname="humact" description="human activity"> <asymbol name="pants"/> </symbolaut> <symbolaut dname="boss" buttonaction="nobutton" description="Stalagmite boss"> <asymbol name="stalboss"/> </symbolaut> <symbolaut dname="helictite" description="Helictite"> <asymbol name="helictite"/> </symbolaut> </set> <set multiplicity="fill" buttonaction="append" position="random" area-interaction="no-overlap"> <symbolaut dname="sand" description="lots of sand"> <asymbol name="sand" scale="fixed" picscale="0.5" orientation="fixed"/> </symbolaut> <symbolaut dname="pebbles" description="pebbly area"> <asymbol name="pebble" scale="fixed" picscale="0.6" orientation="random"/> </symbolaut> <symbolaut dname="mud" description="muddy area"> <asymbol name="mud" scale="andhalf" picscale="0.7" area-interaction="trim" orientation="fixed"/> </symbolaut> <symbolaut dname="boulders" picscale="0.7" description="lots of boulders"> <asymbol name="boulder" scale="andhalf" orientation="random"/> <asymbol name="triangleboulder" scale="andhalf" orientation="random"/> </symbolaut> <symbolaut dname="bigboulders" picscale="1.7" description="lots of big boulders"> <asymbol name="boulder" scale="andhalf" orientation="random"/> <asymbol name="triangleboulder" scale="andhalf" orientation="random"/> </symbolaut> </set> <set multiplicity="fill" position="latticef" area-interaction="trim" buttonaction="overwrite" scale="fixed" orientation="fixed"> <symbolaut dname="puddle" picscale="1.0" description="water area"> <asymbol name="puddle"/> </symbolaut> <symbolaut dname="hexmud" picscale="1.0" description="fractured mud area"> <asymbol name="hexagons"/> </symbolaut> <symbolaut dname="sump" picscale="1.0" description="9x9sump"> <asymbol name="sump"/> </symbolaut> </set> <set multiplicity="fill" buttonaction="overwrite"> <symbolaut dname="flowstone" position="random" picscale="0.5" scale="fixed" orientation="alongaxis" area-interaction="no-overlap" description="calcity area"> <asymbol name="flowstone"/> </symbolaut> <symbolaut dname="flowperp" position="random" picscale="0.5" scale="fixed" orientation="closestfromaxis" area-interaction="no-overlap" description="flowstone perpendicular"> <asymbol name="flowstone"/> </symbolaut> <symbolaut dname="flowpara" position="random" picscale="0.5" scale="fixed" orientation="closestalongaxis" area-interaction="no-overlap" description="flowstone parallel"> <asymbol name="flowstone"/> </symbolaut> <symbolaut dname="neckstream" axisscale="2.0" position="alongpath_even" picscale="0.5" scale="fixed" orientation="alongaxis" area-interaction="allowed-outside-no-overlap" description="stream necklace"> <asymbol name="stream"/> </symbolaut> <symbolaut dname="neckbould" axisscale="0.3" axisscaleperp="30.0" position="alongpath_random_pullback" picscale="0.5" scale="andhalf" orientation="random" area-interaction="no-overlap" description="boulder necklace"> <asymbol name="boulder"/> </symbolaut> <symbolaut dname="neckslope" axisscale="2.0" position="alongpath_even" picscale="0.5" scale="fixed" orientation="alongaxisperp" area-interaction="allowed-outside-no-overlap" description="slope necklace"> <asymbol name="slope" drawstyle="filled"/> </symbolaut> </set> </subsetattr> </groupsubsetattr> <groupsubsetattr groupsubsetname="baseSymbols500" groupsubsetselectable="no"> <subsetattr name="default"/> <subsetattr name="visiblesets"> <set multiplicity="1" buttonaction="overwrite" area-interaction="allowed-outside" position="endpath" scale="fixed" orientation="fixed"> <symbolaut dname="breeze" buttonaction="nobutton" description="breeze symbol"> <asymbol name="breeze" orientation="alongaxis"/> </symbolaut> <symbolaut dname="breeze_a" description="breeze symbol along direction"> <asymbol name="breeze" picscale="-1.0" orientation="alongaxis"/> </symbolaut> <symbolaut dname="slope" description="slope symbol"> <asymbol name="slope" picscale="1.0" orientation="alongaxis" drawstyle="filled"/> </symbolaut> <symbolaut dname="slope2" description="big slope symbol"> <asymbol name="slope" picscale="1.8" orientation="alongaxis" drawstyle="filled"/> </symbolaut> <symbolaut dname="stream" description="stream symbol"> <asymbol name="stream" orientation="nearaxis"/> </symbolaut> <symbolaut dname="stream2" description="big stream symbol"> <asymbol name="stream" picscale="3.0" orientation="nearaxis"/> </symbolaut> <symbolaut dname="bedrock" description="bare solid bedrock"> <asymbol name="bedrock" picscale="2.0"/> </symbolaut> <symbolaut dname="column" description="Stal column"> <asymbol name="column" picscale="2.0"/> </symbolaut> <symbolaut dname="curtain" description="Stal curtain"> <asymbol name="curtain" picscale="2.0"/> </symbolaut> <symbolaut dname="popcorn" description="popcorn formations"> <asymbol name="popcorn" picscale="2.0"/> </symbolaut> <symbolaut dname="stalactite" description="Stalactite"> <asymbol name="stalactite" picscale="2.0"/> </symbolaut> <symbolaut dname="stalagtite" buttonaction="nobutton" description="Misspelled stalactite"> <asymbol name="stalactite" picscale="40.0"/> </symbolaut> <symbolaut dname="stalagmite" description="Stalagmite"> <asymbol name="stalagmite" picscale="2.0"/> </symbolaut> <symbolaut dname="straws" description="Straws"> <asymbol name="straws" picscale="2.0"/> </symbolaut> <symbolaut dname="rats" description="rat activity"> <asymbol name="rats" picscale="2.0"/> </symbolaut> <symbolaut dname="guano" description="bat shit"> <asymbol name="bats" picscale="2.0"/> </symbolaut> <symbolaut dname="humact" description="human activity"> <asymbol name="pants" picscale="2.0"/> </symbolaut> <symbolaut dname="boss" buttonaction="nobutton" description="Stalagmite boss"> <asymbol name="stalboss" picscale="2.0"/> </symbolaut> <symbolaut dname="helictite" description="Helictite"> <asymbol name="helictite" picscale="2.0"/> </symbolaut> </set> <set multiplicity="fill" buttonaction="append" position="random" area-interaction="no-overlap"> <symbolaut dname="sand" description="lots of sand"> <asymbol name="sand" scale="fixed" picscale="2.5" orientation="fixed"/> </symbolaut> <symbolaut dname="pebbles" description="pebbly area"> <asymbol name="pebble" scale="fixed" picscale="1.0" orientation="random"/> </symbolaut> <symbolaut dname="mud" description="muddy area"> <asymbol name="mud" scale="andhalf" picscale="1.5" orientation="fixed"/> </symbolaut> <symbolaut dname="boulders" picscale="1.5" description="lots of boulders"> <asymbol name="boulder" scale="andhalf" orientation="random"/> <asymbol name="triangleboulder" scale="andhalf" orientation="random"/> </symbolaut> <symbolaut dname="bigboulders" picscale="3.5" description="lots of big boulders"> <asymbol name="boulder" scale="andhalf" orientation="random"/> <asymbol name="triangleboulder" scale="andhalf" orientation="random"/> </symbolaut> </set> <set multiplicity="fill" position="latticef" area-interaction="trim" buttonaction="overwrite" scale="fixed" orientation="fixed"> <symbolaut dname="puddle" picscale="2.0" description="water area"> <asymbol name="puddle"/> </symbolaut> <symbolaut dname="hexmud" picscale="2.0" description="fractured mud area"> <asymbol name="hexagons"/> </symbolaut> <symbolaut dname="sump" picscale="2.0" description="9x9sump"> <asymbol name="sump"/> </symbolaut> </set> <set multiplicity="fill" buttonaction="overwrite"> <symbolaut dname="flowstone" position="random" picscale="1.5" scale="fixed" orientation="alongaxis" area-interaction="no-overlap" description="calcity area"> <asymbol name="flowstone"/> </symbolaut> <symbolaut dname="flowperp" position="random" picscale="1.5" scale="fixed" orientation="closestfromaxis" area-interaction="no-overlap" description="flowstone perpendicular"> <asymbol name="flowstone"/> </symbolaut> <symbolaut dname="flowpara" position="random" picscale="1.5" scale="fixed" orientation="closestalongaxis" area-interaction="no-overlap" description="flowstone parallel"> <asymbol name="flowstone"/> </symbolaut> <symbolaut dname="neckstream" axisscale="2.0" position="alongpath_even" picscale="1.5" scale="fixed" orientation="alongaxis" area-interaction="allowed-outside-no-overlap" description="stream necklace"> <asymbol name="stream"/> </symbolaut> <symbolaut dname="neckbould" axisscale="0.3" axisscaleperp="30.0" position="alongpath_random_pullback" picscale="1.5" scale="andhalf" orientation="random" area-interaction="no-overlap" description="boulder necklace"> <asymbol name="boulder"/> </symbolaut> <symbolaut dname="neckslope" axisscale="2.0" position="alongpath_even" picscale="1.0" scale="fixed" orientation="alongaxisperp" area-interaction="allowed-outside-no-overlap" description="slope necklace"> <asymbol name="slope" drawstyle="filled"/> </symbolaut> </set> </subsetattr> </groupsubsetattr> <groupsubsetattr groupsubsetname="baseSymbols1000" groupsubsetselectable="no"> <subsetattr name="default"/> <subsetattr name="visiblesets"> <set multiplicity="1" buttonaction="overwrite" area-interaction="allowed-outside" position="endpath" scale="fixed" orientation="fixed"> <symbolaut dname="breeze" buttonaction="nobutton" description="breeze symbol"> <asymbol name="breeze" picscale="2.8" orientation="alongaxis" area-interaction="allowed-outside"/> </symbolaut> <symbolaut dname="breeze_a" description="breeze symbol along direction"> <asymbol name="breeze" picscale="-2.8" orientation="alongaxis"/> </symbolaut> <symbolaut dname="slope" description="slope symbol"> <asymbol name="slope" picscale="1.5" orientation="alongaxis" drawstyle="filled"/> </symbolaut> <symbolaut dname="slope2" description="big slope symbol"> <asymbol name="slope" picscale="3.0" orientation="alongaxis" drawstyle="filled"/> </symbolaut> <symbolaut dname="stream" description="stream symbol"> <asymbol name="stream" picscale="2.5" orientation="nearaxis"/> </symbolaut> <symbolaut dname="stream2" description="big stream symbol"> <asymbol name="stream" picscale="5.0" orientation="nearaxis"/> </symbolaut> <symbolaut dname="bedrock" description="bare solid bedrock"> <asymbol name="bedrock" picscale="3.5"/> </symbolaut> <symbolaut dname="column" description="stalagmite formation"> <asymbol name="column" picscale="4.5"/> </symbolaut> <symbolaut dname="curtain" description="curtain formation"> <asymbol name="curtain" picscale="4.5"/> </symbolaut> <symbolaut dname="popcorn" description="popcorn formations"> <asymbol name="popcorn" picscale="4.5"/> </symbolaut> <symbolaut dname="stalagmite" description="stalagmite formation"> <asymbol name="stalagmite" picscale="4.5"/> </symbolaut> <symbolaut dname="stalactite" description="stalagmite formation"> <asymbol name="stalactite" picscale="4.5"/> </symbolaut> <symbolaut dname="stalagtite" buttonaction="nobutton" description="misspelt stalagmite formation"> <asymbol name="stalactite" picscale="50.0"/> </symbolaut> <symbolaut dname="stalagmite" description="Stalagmite formation"> <asymbol name="stalagmite" picscale="4.5"/> </symbolaut> <symbolaut dname="straws" description="straw formations"> <asymbol name="straws" picscale="4.5"/> </symbolaut> <symbolaut dname="rats" description="rat activity"> <asymbol name="rats" picscale="3.5"/> </symbolaut> <symbolaut dname="guano" description="bat shit"> <asymbol name="bats" picscale="3.5"/> </symbolaut> <symbolaut dname="humact" description="human activity"> <asymbol name="pants" picscale="3.5"/> </symbolaut> <symbolaut dname="helictite" description="Helictite"> <asymbol name="helictite" picscale="3.5"/> </symbolaut> </set> <set multiplicity="fill" buttonaction="append" position="random" area-interaction="no-overlap"> <symbolaut dname="sand" description="lots of sand"> <asymbol name="sand" scale="fixed" picscale="2.5" orientation="fixed"/> </symbolaut> <symbolaut dname="pebbles" description="pebbly area"> <asymbol name="pebble" scale="fixed" picscale="2.0" orientation="random"/> </symbolaut> <symbolaut dname="mud" description="muddy area"> <asymbol name="mud" scale="andhalf" picscale="1.5" orientation="fixed"/> </symbolaut> <symbolaut dname="boulders" picscale="1.5" description="lots of boulders"> <asymbol name="boulder" scale="andhalf" orientation="random"/> <asymbol name="triangleboulder" scale="andhalf" orientation="random"/> </symbolaut> <symbolaut dname="bigboulders" picscale="3.5" description="lots of big boulders"> <asymbol name="boulder" scale="andhalf" orientation="random"/> <asymbol name="triangleboulder" scale="andhalf" orientation="random"/> </symbolaut> </set> <set multiplicity="fill" position="latticef" area-interaction="trim" buttonaction="overwrite" scale="fixed" orientation="fixed"> <symbolaut dname="puddle" picscale="4.5" description="water area"> <asymbol name="puddle"/> </symbolaut> <symbolaut dname="hexmud" picscale="4.5" description="fractured mud area"> <asymbol name="hexagons"/> </symbolaut> <symbolaut dname="sump" picscale="4.5" description="9x9sump"> <asymbol name="sump"/> </symbolaut> </set> <set multiplicity="fill" buttonaction="overwrite"> <symbolaut dname="flowstone" position="random" picscale="2.5" scale="fixed" orientation="alongaxis" area-interaction="no-overlap" description="calcity area"> <asymbol name="flowstone"/> </symbolaut> <symbolaut dname="flowperp" position="random" picscale="2.5" scale="fixed" orientation="closestfromaxis" area-interaction="no-overlap" description="flowstone perpendicular"> <asymbol name="flowstone"/> </symbolaut> <symbolaut dname="flowpara" position="random" picscale="2.5" scale="fixed" orientation="closestalongaxis" area-interaction="no-overlap" description="flowstone parallel"> <asymbol name="flowstone"/> </symbolaut> <symbolaut dname="neckstream" axisscale="2.0" position="alongpath_even" picscale="2.5" scale="fixed" orientation="alongaxis" area-interaction="allowed-outside-no-overlap" description="stream necklace"> <asymbol name="stream"/> </symbolaut> <symbolaut dname="neckbould" axisscale="0.3" axisscaleperp="30.0" position="alongpath_random_pullback" picscale="1.5" scale="andhalf" orientation="random" area-interaction="no-overlap" description="boulder necklace"> <asymbol name="boulder"/> </symbolaut> <symbolaut dname="neckslope" axisscale="2.0" position="alongpath_even" picscale="1.7" scale="fixed" orientation="alongaxisperp" area-interaction="allowed-outside-no-overlap" description="slope necklace"> <asymbol name="slope" drawstyle="filled"/> </symbolaut> </set> </subsetattr> </groupsubsetattr> <groupsubsetattr groupsubsetname="baseSymbols4000" groupsubsetselectable="no"> <subsetattr name="default"/> <subsetattr name="visiblesets"> <set multiplicity="1" buttonaction="overwrite" area-interaction="no-overlap"> <symbolaut dname="slope" description="slope symbol"> <asymbol name="slope" position="endpath" scale="fixed" picscale="3" orientation="alongaxis" drawstyle="filled"/> </symbolaut> <symbolaut dname="breeze" buttonaction="nobutton" description="breeze symbol"> <asymbol name="breeze" position="endpath" scale="fixed" picscale="1.5" orientation="alongaxis" area-interaction="allowed-outside"/> </symbolaut> <symbolaut dname="breeze_a" description="breeze symbol"> <asymbol name="breeze" position="endpath" scale="fixed" picscale="-1.5" orientation="alongaxis" area-interaction="allowed-outside"/> </symbolaut> <symbolaut dname="stream" description="stream symbol"> <asymbol name="stream" position="endpath" scale="fixed" picscale="3" orientation="nearaxis"/> </symbolaut> <symbolaut dname="stalagmite" description="Stalagmite"> <asymbol name="stalagmite" position="endpath" scale="fixed" picscale="3" orientation="fixed" area-interaction="trim"/> </symbolaut> <symbolaut dname="stalagtite" buttonaction="nobutton" description="Misspelled stalactite"> <asymbol name="stalagtite" position="endpath" scale="fixed" picscale="3" orientation="fixed" area-interaction="trim"/> </symbolaut> <symbolaut dname="column" description="Stal column"> <asymbol name="column" position="endpath" scale="fixed" picscale="3" orientation="fixed" area-interaction="trim"/> </symbolaut> <symbolaut dname="curtain" description="Stal curtain"> <asymbol name="curtain" position="endpath" scale="fixed" picscale="3" orientation="fixed" area-interaction="trim"/> </symbolaut> <symbolaut dname="straws" description="Straws"> <asymbol name="straws" position="endpath" scale="fixed" picscale="3" orientation="fixed" area-interaction="trim"/> </symbolaut> <symbolaut dname="snow" description="9x9snow"> <asymbol name="snow" position="lattice" scale="fixed" picscale="3" orientation="fixed" multiplicity="441" area-interaction="trim"/> </symbolaut> <symbolaut dname="puddle" description="9x9puddle"> <asymbol name="puddle" position="lattice" scale="fixed" picscale="3" orientation="fixed" multiplicity="441" area-interaction="trim"/> </symbolaut> <symbolaut dname="sump" description="9x9sump"> <asymbol name="sump" position="lattice" scale="fixed" picscale="3" orientation="fixed" multiplicity="441" area-interaction="trim"/> </symbolaut> <symbolaut dname="hexmud" description="cracked mud"> <asymbol name="hexagons" position="lattice" scale="fixed" picscale="3" orientation="fixed" multiplicity="441" area-interaction="trim"/> </symbolaut> <symbolaut dname="sand" buttonaction="append" description="lots of sand"> <asymbol name="sand" position="random" scale="fixed" picscale="3" orientation="fixed" multiplicity="fill"/> </symbolaut> <symbolaut dname="bigboulder" buttonaction="nobutton" description="boulder"> <asymbol name="bigboulder1" position="random" scale="andhalf" picscale="3" orientation="random" multiplicity="1"/> </symbolaut> <symbolaut dname="bigboulders" buttonaction="append" description="lots of big boulders"> <asymbol name="bigboulder1" position="random" scale="andhalf" picscale="3" orientation="random" multiplicity="fill"/> <asymbol name="bigboulder2" position="random" scale="andhalf" picscale="3" orientation="random" multiplicity="fill"/> </symbolaut> <symbolaut dname="pebbles" buttonaction="append" description="some pebbles"> <asymbol name="pebble" position="random" scale="fixed" picscale="3" orientation="fixed" multiplicity="fill"/> </symbolaut> <symbolaut dname="mud" buttonaction="append" description="muddy area"> <asymbol name="mud" position="random" scale="fixed" picscale="3" orientation="fixed" multiplicity="fill"/> </symbolaut> </set> </subsetattr> </groupsubsetattr> </fontcolours> </tunnelxml> ���������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/curtain.xml�����������������������������������������������������������0000644�0000000�0000000�00000002262�12066375447�015166� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:09"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="centreline" splined="1"> <pt X="30.0" Y="-180.0"/> <pt X="30.0" Y="-180.0"/> </skpath> <skpath from="2" to="0" linestyle="detail"> <pt X="27.131954" Y="-182.90779"/> <pt X="30.0" Y="-180.0"/> </skpath> <skpath from="3" to="0" linestyle="detail"> <pt X="32.585964" Y="-182.66211"/> <pt X="30.0" Y="-180.0"/> </skpath> <skpath from="4" to="5" linestyle="centreline" splined="1"> <pt X="29.293903" Y="-179.17351"/> <pt X="30.866232" Y="-179.17351"/> </skpath> <skpath from="1" to="6" linestyle="detail" splined="1"> <pt X="30.0" Y="-180.0"/> <pt X="30.13806" Y="-178.91072"/> <pt X="29.126791" Y="-177.43082"/> <pt X="30.680693" Y="-176.07423"/> <pt X="29.274782" Y="-174.56967"/> <pt X="30.730022" Y="-173.36108"/> <pt X="29.965405" Y="-172.27582"/> <pt X="29.965405" Y="-171.09189"/> </skpath> </sketch> </tunnelxml> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/northarrowbig.xml�����������������������������������������������������0000755�0000000�0000000�00000003572�12066375447�016420� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:09"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="centreline" splined="1"> <pt X="0.0" Y="-670.0"/> <pt X="0.0" Y="-700.0"/> </skpath> <skpath from="2" to="3" linestyle="detail"> <pt X="0.0" Y="-900.0"/> <pt X="0.0" Y="-600.0"/> </skpath> <skpath from="3" to="4" linestyle="filled"> <pt X="0.0" Y="-600.0"/> <pt X="100.0" Y="-500.0"/> <pt X="0.0" Y="-900.0"/> </skpath> <skpath from="3" to="2" linestyle="wall"> <pt X="0.0" Y="-600.0"/> <pt X="-100.0" Y="-500.0"/> <pt X="0.0" Y="-900.0"/> </skpath> <skpath from="0" to="3" linestyle="connective"> <pt X="0.0" Y="-670.0"/> <pt X="-13.654076" Y="-625.5605"/> <pt X="0.0" Y="-600.0"/> </skpath> <skpath from="2" to="5" linestyle="invisible" splined="1"> <pt X="0.0" Y="-900.0"/> <pt X="0.0" Y="-910.0"/> </skpath> <skpath from="5" to="6" linestyle="invisible" splined="1"> <pt X="0.0" Y="-910.0"/> <pt X="110.0" Y="-490.0"/> </skpath> <skpath from="6" to="7" linestyle="invisible" splined="1"> <pt X="110.0" Y="-490.0"/> <pt X="90.0" Y="-490.0"/> </skpath> <skpath from="7" to="8" linestyle="invisible" splined="1"> <pt X="90.0" Y="-490.0"/> <pt X="0.0" Y="-590.0"/> </skpath> <skpath from="8" to="9" linestyle="invisible" splined="1"> <pt X="0.0" Y="-590.0"/> <pt X="-90.0" Y="-490.0"/> </skpath> <skpath from="9" to="10" linestyle="invisible" splined="1"> <pt X="-90.0" Y="-490.0"/> <pt X="-110.0" Y="-490.0"/> </skpath> <skpath from="10" to="5" linestyle="invisible" splined="1"> <pt X="-110.0" Y="-490.0"/> <pt X="0.0" Y="-910.0"/> </skpath> </sketch> </tunnelxml> ��������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/hexagons.xml����������������������������������������������������������0000644�0000000�0000000�00000005106�12066375447�015335� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:09"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="centreline"> <pt X="-82.5" Y="-20.0"/> <pt X="-82.5" Y="-25.0"/> </skpath> <skpath from="2" to="1" linestyle="invisible"> <pt X="-80.0" Y="-25.0"/> <pt X="-82.5" Y="-25.0"/> </skpath> <skpath from="3" to="1" linestyle="invisible"> <pt X="-85.0" Y="-20.0"/> <pt X="-85.0" Y="-25.0"/> <pt X="-82.5" Y="-25.0"/> </skpath> <skpath from="3" to="0" linestyle="invisible" splined="1"> <pt X="-85.0" Y="-20.0"/> <pt X="-82.5" Y="-20.0"/> </skpath> <skpath from="2" to="0" linestyle="invisible"> <pt X="-80.0" Y="-25.0"/> <pt X="-80.0" Y="-20.0"/> <pt X="-82.5" Y="-20.0"/> </skpath> <skpath from="4" to="5" linestyle="detail"> <pt X="-84.994965" Y="-24.977829"/> <pt X="-83.18221" Y="-24.990871"/> </skpath> <skpath from="5" to="6" linestyle="detail"> <pt X="-83.18221" Y="-24.990871"/> <pt X="-82.295395" Y="-23.543276"/> </skpath> <skpath from="6" to="7" linestyle="detail"> <pt X="-82.295395" Y="-23.543276"/> <pt X="-80.886925" Y="-23.530235"/> </skpath> <skpath from="7" to="2" linestyle="detail"> <pt X="-80.886925" Y="-23.530235"/> <pt X="-80.0" Y="-25.0"/> </skpath> <skpath from="8" to="9" linestyle="detail" splined="1"> <pt X="-85.03409" Y="-22.343468"/> <pt X="-83.15613" Y="-22.343468"/> </skpath> <skpath from="9" to="10" linestyle="detail" splined="1"> <pt X="-83.15613" Y="-22.343468"/> <pt X="-82.295395" Y="-21.300158"/> </skpath> <skpath from="10" to="11" linestyle="detail" splined="1"> <pt X="-82.295395" Y="-21.300158"/> <pt X="-83.15613" Y="-20.035141"/> </skpath> <skpath from="6" to="9" linestyle="detail"> <pt X="-82.295395" Y="-23.543276"/> <pt X="-83.15613" Y="-22.343468"/> </skpath> <skpath from="7" to="12" linestyle="detail"> <pt X="-80.886925" Y="-23.530235"/> <pt X="-80.03924" Y="-22.395634"/> </skpath> <skpath from="12" to="13" linestyle="detail"> <pt X="-80.03924" Y="-22.395634"/> <pt X="-80.873886" Y="-21.247992"/> </skpath> <skpath from="13" to="10" linestyle="detail"> <pt X="-80.873886" Y="-21.247992"/> <pt X="-82.295395" Y="-21.300158"/> </skpath> <skpath from="13" to="14" linestyle="detail"> <pt X="-80.873886" Y="-21.247992"/> <pt X="-80.01315" Y="-20.035141"/> </skpath> </sketch> </tunnelxml> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/npit.xml��������������������������������������������������������������0000644�0000000�0000000�00000004056�12066375447�014476� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:09"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="centreline"> <pt X="-1.0" Y="0.0"/> <pt X="1.0" Y="0.0"/> </skpath> <skpath from="2" to="2" linestyle="detail" splined="1"> <pt X="-1.0" Y="0.0"/> <pt X="-0.951057" Y="0.309017"/> <pt X="-0.809017" Y="0.587785"/> <pt X="-0.587785" Y="0.809017"/> <pt X="-0.309017" Y="0.951057"/> <pt X="-0.0" Y="1.0"/> <pt X="0.309017" Y="0.951057"/> <pt X="0.587785" Y="0.809017"/> <pt X="0.809017" Y="0.587785"/> <pt X="0.951057" Y="0.309017"/> <pt X="1.0" Y="0.0"/> <pt X="0.951057" Y="-0.309017"/> <pt X="0.809017" Y="-0.587785"/> <pt X="0.587785" Y="-0.809017"/> <pt X="0.309017" Y="-0.951057"/> <pt X="0.0" Y="-1.0"/> <pt X="-0.309017" Y="-0.951057"/> <pt X="-0.587785" Y="-0.809017"/> <pt X="-0.809017" Y="-0.587785"/> <pt X="-0.951057" Y="-0.309017"/> <pt X="-1.0" Y="0.0"/> </skpath> <skpath from="3" to="3" linestyle="detail" splined="1"> <pt X="-0.8" Y="0.0"/> <pt X="-0.760845" Y="0.247214"/> <pt X="-0.647214" Y="0.470228"/> <pt X="-0.470228" Y="0.647214"/> <pt X="-0.247214" Y="0.760845"/> <pt X="-0.0" Y="0.8"/> <pt X="0.247214" Y="0.760845"/> <pt X="0.470228" Y="0.647214"/> <pt X="0.647214" Y="0.470228"/> <pt X="0.760845" Y="0.247214"/> <pt X="0.8" Y="0.0"/> <pt X="0.760845" Y="-0.247214"/> <pt X="0.647214" Y="-0.470228"/> <pt X="0.470228" Y="-0.647214"/> <pt X="0.247214" Y="-0.760845"/> <pt X="0.0" Y="-0.8"/> <pt X="-0.247214" Y="-0.760845"/> <pt X="-0.470228" Y="-0.647214"/> <pt X="-0.647214" Y="-0.470228"/> <pt X="-0.760845" Y="-0.247214"/> <pt X="-0.8" Y="0.0"/> </skpath> <skpath from="2" to="3" linestyle="invisible" splined="1"> <pt X="-1.0" Y="0.0"/> <pt X="-0.8" Y="0.0"/> </skpath> </sketch> </tunnelxml> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/symbols/flowstone.xml���������������������������������������������������������0000644�0000000�0000000�00000002152�12066375447�015537� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='us-ascii'?> <tunnelxml tunnelversion="version2011-08-01 Austria" tunnelproject="cuccaustria" tunneluser="austria11" tunneldate="2012-06-09 20:02:09"> <sketch splined="0" locoffsetx="0.0" locoffsety="0.0" locoffsetz="0.0" realpaperscale="1000.0"> <skpath from="0" to="1" linestyle="centreline"> <pt X="2114.232" Y="-329.017"/> <pt X="2114.3896" Y="-323.4041"/> </skpath> <skpath from="2" to="3" linestyle="detail" splined="1"> <pt X="2112.043" Y="-323.91577"/> <pt X="2112.6868" Y="-323.1834"/> <pt X="2114.2634" Y="-322.64734"/> <pt X="2115.9348" Y="-322.67886"/> <pt X="2117.0068" Y="-323.12033"/> <pt X="2117.6375" Y="-323.9402"/> </skpath> <skpath from="2" to="4" linestyle="invisible" splined="1"> <pt X="2112.043" Y="-323.91577"/> <pt X="2112.1191" Y="-324.88617"/> </skpath> <skpath from="4" to="2" linestyle="invisible"> <pt X="2112.1191" Y="-324.88617"/> <pt X="2117.89" Y="-324.91772"/> <pt X="2117.8582" Y="-322.26895"/> <pt X="2112.0876" Y="-322.4897"/> <pt X="2112.043" Y="-323.91577"/> </skpath> </sketch> </tunnelxml> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/darkside_build_tunnel.bat�����������������������������������������������������0000644�0000000�0000000�00000000076�11762432750�016323� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������"c:\program files\java\jdk1.5.0_02\bin\javac" -d . src\*.java ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/cavesax.py��������������������������������������������������������������������0000644�0000000�0000000�00000015221�11762432750�013303� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import vtk import sys from math import sqrt from xml.sax.handler import ContentHandler from xml.sax.xmlreader import InputSource from xml.sax import make_parser def MakeDelaunConstr(mspts): onepolylines = vtk.vtkCellArray() onepolylines.InsertNextCell(mspts.GetNumberOfPoints()) # for i in range(mspts.GetNumberOfPoints()): # onepolylines.InsertCellPoint(i) # onepolylines.InsertCellPoint(0) for i in range(mspts.GetNumberOfPoints()): onepolylines.InsertCellPoint(mspts.GetNumberOfPoints() - 1 - i) # onepolylines.InsertCellPoint(mspts.GetNumberOfPoints() - 1) onepoly = vtk.vtkPolyData() onepoly.SetPoints(mspts) onepoly.SetPolys(onepolylines) delaun = vtk.vtkDelaunay2D() delaun.SetInput(onepoly) delaun.SetSource(onepoly) print mspts.GetNumberOfPoints() return delaun.GetOutput() class CHandler(ContentHandler): def __init__(self): pass def FindZ(self, x0, y0, z0, x1, y1, z1, x2, y2): diffx10 = x1 - x0 diffx20 = x2 - x0 diffy10 = y1 - y0 diffy20 = y2 - y0 n = diffx10 * diffx20 + diffy10 * diffy20 d = diffx10 * diffx10 + diffy10 * diffy10 d = sqrt(d) r = n / (d * d) return (1.0 - r) * z0 + r * z1 def startElement(self, name, attrs): output_function = getattr(self, "start_%s" % name, self.start_unkown_tag) output_function(name, attrs) def start_tunnelxpyvtk(self, name, attrs): self.pyvtkareaIndex = -1 self.appendF = vtk.vtkAppendPolyData() def start_pyvtkarea(self, name, attrs): self.pyvtkareaIndex += 1 if self.pyvtkareaIndex % 100 == 0: print "pyvtkareaIndex:%d" % self.pyvtkareaIndex self.ms = vtk.vtkFloatArray() self.mspts = vtk.vtkPoints() self.ms.SetNumberOfComponents(3) self.polygon = vtk.vtkPolygon() def start_path(self, name, attrs): self.Points = [] for attrName in attrs.keys(): if attrName == "zstart": self.z0 = float(attrs.get(attrName)) elif attrName == "zend": self.z1 = float(attrs.get(attrName)) elif attrName == "reversed": self.reversed = int(attrs.get(attrName)) def start_pt(self, name, attrs): for attrName in attrs.keys(): if attrName == "x": self.x = float(attrs.get(attrName)) elif attrName == "y": self.y = float(attrs.get(attrName)) self.Points.append([self.x,self.y]) def start_unkown_tag(self, name, attrs): if name == None: print "Warning:no name given for tag" else: print "start of unknown tag:%s" % name for attrName in attrs.keys(): print "Attribute -- Name: %s Value: %s" % (attrName, attrs.get(attrName)) def endElement(self, name): output_function = getattr(self, "end_%s" % name, self.end_unkown_tag) output_function(name) def end_pyvtkarea(self, name): self.appendF.AddInput(MakeDelaunConstr(self.mspts)) return polygon = self.polygon polygon.GetPoints().SetData(self.ms) n = polygon.GetPoints().GetNumberOfPoints() ids = polygon.GetPointIds() ids.SetNumberOfIds(n) for i in range(n): ids.SetId(i,i) ids = vtk.vtkIdList() polygon.Triangulate(ids) numberOfIds = ids.GetNumberOfIds() numberOfTriangles = numberOfIds / 3 if ids.GetNumberOfIds() != numberOfTriangles * 3: print "id list should contain a multipul of 3 points" cellArray = vtk.vtkCellArray() for triIndex in range(numberOfTriangles): a = ids.GetId(3 * triIndex) b = ids.GetId(3 * triIndex + 1) c = ids.GetId(3 * triIndex + 2) cellArray.InsertNextCell(3) cellArray.InsertCellPoint(a) cellArray.InsertCellPoint(b) cellArray.InsertCellPoint(c) pD = vtk.vtkPolyData() points = vtk.vtkPoints() points.SetData(self.ms) pD.SetPoints(points) #pD.SetPoints(self.polygon.GetPoints()) pD.SetPolys(cellArray) self.appendF.AddInput(pD) def end_tunnelxpyvtk(self, name): print "pyvtkareaIndex:%d" % self.pyvtkareaIndex def end_path(self, name): z0 = self.z0 z1 = self.z1 reversed = self.reversed points = self.Points if reversed == 1: points.reverse() tmp = z0 z0 = z1 z1 = z0 ptstart = points[0] ptend = points[-1] x0 = ptstart[0] y0 = ptstart[1] x1 = ptend[0] y1 = ptend[1] if x0 == x1 and y0 == y1 and z0 != z1: print "the data is a bit nasty, but I shouldnt crash!" for point in points[:-1]: x2 = point[0] y2 = point[1] if z0 == z1: z2 = z0 else: z2 = self.FindZ(x0, y0, z0, x1, y1, z1, x2, y2) self.ms.InsertNextTuple3(x2, y2, z2) self.mspts.InsertNextPoint(x2, y2, z2) #self.polygon.GetPoints().InsertNextPoint(x2, y2, z2) def end_pt(self, name): pass def end_unkown_tag(self, name): if name == None: print "Warning:end of tag:no name given for tag" else: print "end of unknown tag:%s" % name # the main part xmlfilename = len(sys.argv) >= 2 and sys.argv[1] or 'forsimon.xml' handler = CHandler() xmlParser = make_parser() xmlParser.setContentHandler(handler) xmlParser.setErrorHandler(handler); xmlParser.parse(InputSource(xmlfilename)) mapper = vtk.vtkPolyDataMapper() mapper.SetInput(handler.appendF.GetOutput()) ####### if False: ppp = [ (0, 0, 0), (0, 3, 0), (2, 3, 1), (3, 6, 1), (0, 6, 0), (0, 10, 0), (10, 10, 0), (10, 0, 0) ] ppp.reverse() #del ppp[1] polylines = vtk.vtkCellArray() pts = vtk.vtkPoints() polylines.InsertNextCell(len(ppp) + 1) i0 = -1 for p in ppp: i = pts.InsertNextPoint(p[0], p[1], p[2]) if i0 == -1: i0 = i polylines.InsertCellPoint(i) print i polylines.InsertCellPoint(i0) polyData = MakeDelaunConstr(pts) mapMesh = vtk.vtkPolyDataMapper() mapMesh.SetInput(MakeDelaunConstr(pts)) ######## actor = vtk.vtkActor() actor.SetMapper(mapper) ren = vtk.vtkRenderer() renWin = vtk.vtkRenderWindow() renWin.AddRenderer(ren) iren = vtk.vtkRenderWindowInteractor() iren.SetRenderWindow(renWin) ren.AddActor(actor) ren.SetBackground(0.1, 0.2, 0.4) renWin.SetSize(500, 500) cam1 = ren.GetActiveCamera() cam1.Elevation(-30) cam1.Roll(-20) ren.ResetCameraClippingRange() iren.Initialize() renWin.Render() iren.Start() �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/b�����������������������������������������������������������������������������0000755�0000000�0000000�00000000172�11762432750�011445� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/bash #export LD_LIBRARY_PATH=/home/goatchurch/expo/tunnelx/j3dlib/i386 javac -target 1.5 -version -d . src/*.java ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/b.bat�������������������������������������������������������������������������0000755�0000000�0000000�00000000135�11762432750�012211� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������"C:\Program Files\Java\jdk1.6.0_26\bin\javac" -target 1.5 -Xlint:deprecation -d . src\*.java �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/bh.bat������������������������������������������������������������������������0000644�0000000�0000000�00000000060�11762432750�012353� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������"d:\java\jdk1.5.0_03\bin\javac" -d . src\*.java ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tunnelx-20140102.orig/ri.bat������������������������������������������������������������������������0000644�0000000�0000000�00000000171�12261213471�012367� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������java -showversion -ea -Xmx1000M -cp . Tunnel.MainBox --makeimages --twotone C:\\Users\\goatchurch\\caving\\tunneldata\\ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������