/* * This file is part of MoleculeViewer. * * MoleculeViewer is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * MoleculeViewer 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with MoleculeViewer. If not, see <http://www.gnu.org/licenses/>. */ package astex; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; public class ViewCommand { private static int defaultWidth = 400; private static int defaultHeight = 300; private static int defaultSample = 1; public static int stepMultiple = 1; private static String defaultImage = "movie/image_%04d.bmp"; private static boolean defaultCompress = false; private static int tempBuffer[] = null; /** Execute a view command. */ public static void execute(MoleculeViewer mv, Arguments args){ MoleculeRenderer mr = mv.getMoleculeRenderer(); double zrot = args.getDouble("-rotatez", Double.NEGATIVE_INFINITY); Object antialiasString = args.get("-antialias"); Object realSpheres = args.get("-realspheres"); Object renderDebugString = args.get("-renderdebug"); String image = args.getString("-writeimage", null); if(args.get("-defaultwidth") != null){ defaultWidth = args.getInteger("-defaultwidth", 400); } if(args.get("-defaultheight") != null){ defaultHeight = args.getInteger("-defaultheight", 300); } if(args.get("-defaultsample") != null){ defaultSample = args.getInteger("-defaultsample", 1); } stepMultiple = args.getInteger("-stepmultiple", 1); if(args.get("-defaultimage") != null){ defaultImage = (String)args.get("-defaultimage"); } if(args.get("-defaultcompress") != null){ defaultCompress = args.getBoolean("-defaultcompress", false); } if(args.get("-ambient") != null){ int amb = args.getInteger("-ambient", 64); mr.renderer.setAmbient(Color32.pack(amb, amb, amb)); } if(args.get("-normalcutoff") != null){ double c = args.getDouble("-normalcutoff", 0.07); mr.renderer.setCartoonNormalCutoff(c); } if(args.get("-lightingmodel") != null){ String model = args.getString("-lightingmodel", "normal"); if("normal".equals(model)){ mr.renderer.setLightingModel(Renderer.LightingModel.DefaultLightingModel); }else if("cartoon".equals(model)){ mr.renderer.setLightingModel(Renderer.LightingModel.CartoonLightingModel); }else{ Log.error("unknown lighting model: " + model); } } if(args.get("-gradient") != null){ mr.renderer.setGradient(args.getBoolean("-gradient", false)); } if(args.get("-gradienttop") != null){ mr.renderer.setGradientTop(args.getColor("-gradienttop", Color32.black)); } if(args.get("-gradientbottom") != null){ mr.renderer.setGradientBottom(args.getColor("-gradientbottom", Color32.black)); } if(args.get("-wuantialias") != null){ mr.renderer.wuAntiAlias = args.getBoolean("-wuantialias", false); System.out.println("wu " + mr.renderer.wuAntiAlias); } if(image != null){ int width = args.getInteger("-width", -1); int height = args.getInteger("-height", -1); int sample = args.getInteger("-sample", -1); int multiple = args.getInteger("-multiple", -1); boolean compress = args.getBoolean("-compress", false); int oldWidth = -1; int oldHeight = -1; if("default".equals(image)){ image = defaultImage; } if(multiple > 0){ width = mr.renderer.pixelWidth * multiple; height = mr.renderer.pixelHeight * multiple; } if(width == -1 && height == -1){ width = defaultWidth; height = defaultHeight; } if(sample == -1){ sample = defaultSample; } int previousSample = mr.renderer.getSamples(); width *= sample; height *= sample; if(width != -1 && height != -1){ oldWidth = mr.renderer.pixelWidth; oldHeight = mr.renderer.pixelHeight; System.out.println("Image size " + width + "x" + height); double mb = (width*height*8)/(1024.0*1024.0); FILE.out.print("Approximate memory use %.1fMb\n", mb); mv.resetAwtImage(); mr.renderer.setSamples(sample); mr.renderer.setSize(width, height); mr.paint(); } if(!compress && defaultCompress){ compress = true; } if(sample != 1){ BufferedImage bi = new BufferedImage(mr.renderer.pixelWidth/sample, mr.renderer.pixelHeight/sample, BufferedImage.TYPE_INT_RGB); doAntialias(mr.renderer.pbuffer, mr.renderer.pixelWidth, mr.renderer.pixelHeight, sample, bi); File outputfile = new File(image); try { javax.imageio.ImageIO.write(bi, "png", outputfile); } catch (IOException ex) { Logger.getLogger(ViewCommand.class.getName()).log(Level.SEVERE, null, ex); } }else{ BufferedImage bi = new BufferedImage(mr.renderer.pixelWidth, mr.renderer.pixelHeight, BufferedImage.TYPE_INT_RGB); bi.setRGB(0, 0, mr.renderer.pixelWidth, mr.renderer.pixelHeight, mr.renderer.pbuffer, 0, mr.renderer.pixelWidth); File outputfile = new File(image); try { javax.imageio.ImageIO.write(bi, "png", outputfile); } catch (IOException ex) { Logger.getLogger(ViewCommand.class.getName()).log(Level.SEVERE, null, ex); } } System.out.println("done."); if(oldHeight != -1 || oldWidth != -1){ mr.renderer.setSize(oldWidth, oldHeight); // need to force the awtimage to reflect // the (possibly) new pixel buffer // ... this is a mess mv.resetAwtImage(); mr.paint(); } mr.renderer.setSamples(previousSample); } if(zrot != Double.NEGATIVE_INFINITY){ mr.renderer.rotateY(zrot); } if(args.defined("-wrapangle")){ mr.renderer.setWrapAngle(Math.PI * args.getDouble("-wrapangle", 90.0)/180.0); } if(args.defined("-aagamma")){ mr.renderer.setDrawGamma(args.getDouble("-aagamma", 2.35)); } if(args.defined("-powfactor")){ mr.renderer.setPowFactor(args.getDouble("-powfactor", 1.0)); } if(antialiasString != null){ boolean antialias = args.getBoolean("-antialias", false); mr.renderer.setAntiAlias(antialias); } if(realSpheres != null){ boolean spheres = args.getBoolean("-realspheres", false); mr.renderer.analyticalSpheres = spheres; } if(renderDebugString != null){ boolean renderDebug = args.getBoolean("-renderdebug", false); mr.renderer.debug = renderDebug; } if(args.get("-solidfonts") != null){ mr.hersheyFonts = args.getBoolean("-solidfonts", false); } if(args.get("-shadows") != null){ mr.shadows = args.getBoolean("-shadows", false); } if(args.get("-background") != null){ String colorName = args.getString("-background", "white"); int color = Color32.getColorFromName(colorName); mr.renderer.setBackgroundColor(color); } if(args.get("-fog") != null){ boolean f = args.getBoolean("-fog", false); mr.renderer.depthcue = f; } mv.dirtyRepaint(); } private static void doAntialias(int pbuffer[], int w, int h, int sample, BufferedImage bi){ int wa = w / sample; int ha = h / sample; int sample2 = sample * sample; for(int j = 0; j < ha; j++){ for(int i = 0; i < wa; i++){ int r = 0; int g = 0; int b = 0; for(int iys = 0; iys < sample; iys++){ int iy = j * sample + iys; for(int ixs = 0; ixs < sample; ixs++){ int ix = i * sample + ixs; int index = ix + w * iy; int rgb = pbuffer[index]; int rp = (rgb >> 16) & 0xff; int gp = (rgb >> 8) & 0xff; int bp = (rgb & 0xff); r += rp; g += gp; b += bp; } } r /= sample2; g /= sample2; b /= sample2; bi.setRGB(i, j, Color32.pack(r, g, b)); } } } }