package net.hvidtfeldts.meshia.gui; import groovy.lang.GroovyClassLoader; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.imageio.ImageIO; import javax.media.opengl.GLProfile; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTextArea; import javax.swing.ProgressMonitor; import javax.swing.ScrollPaneConstants; import javax.swing.SwingUtilities; import net.hvidtfeldts.meshia.engine3d.Engine; import net.hvidtfeldts.meshia.engine3d.Object3D; import net.hvidtfeldts.meshia.engine3d.OpenGlWindow; import net.hvidtfeldts.meshia.engine3d.SimpleMarchingCubes; import net.hvidtfeldts.meshia.gui.TextDialog.CloseAction; import net.hvidtfeldts.meshia.math.Vector3; import net.hvidtfeldts.utils.Logger; public class MainWindow extends JFrame { private static final long serialVersionUID = 1L; private final OpenGlWindow openGlWindow; private final Project project = new Project(); private final Engine engine; static { // Initialize OpenGL GLProfile.initSingleton(); } public MainWindow() { setLayout(new BorderLayout()); setTitle("Meshia - Mesh Generator"); List<Image> icons = new ArrayList<>(); try { icons.add(ImageIO.read(getClass().getResourceAsStream("/res/icons/icon16.png"))); icons.add(ImageIO.read(getClass().getResourceAsStream("/res/icons/icon24.png"))); icons.add(ImageIO.read(getClass().getResourceAsStream("/res/icons/icon32.png"))); icons.add(ImageIO.read(getClass().getResourceAsStream("/res/icons/icon48.png"))); icons.add(ImageIO.read(getClass().getResourceAsStream("/res/icons/icon256.png"))); } catch (IOException e) { e.printStackTrace(); System.exit(1); } setIconImages(icons); engine = new Engine(project); openGlWindow = OpenGlWindow.createOpenGlWindow(engine); engine.setPanel(openGlWindow); JSplitPane mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); splitPane.add(openGlWindow); splitPane.add(createButtonsAndLogPanel()); splitPane.setDividerLocation(300); ProjectView pw = new ProjectView(); pw.setModel(project); mainSplitPane.setDividerLocation(150); mainSplitPane.add(pw); mainSplitPane.add(splitPane); add(mainSplitPane, BorderLayout.CENTER); setupMenus(); openGlWindow.setPreferredSize(new Dimension(400, 400)); setSize(new Dimension(400, 500)); this.invalidate(); } private JPanel createButtonsAndLogPanel() { JPanel jp = new JPanel(); jp.setLayout(new BorderLayout()); JPanel buttonPanel = createButtonPanel(); jp.add(buttonPanel, BorderLayout.NORTH); TextAreaLogger tal = new TextAreaLogger(); Logger.setLogger(tal); jp.add(tal.createComponent(), BorderLayout.CENTER); return jp; } private JPanel createButtonPanel() { JPanel buttonPanel = new JPanel(); buttonPanel.setLayout(new FlowLayout()); final JButton inputButton = new JButton("Input"); buttonPanel.add(inputButton); inputButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { JPopupMenu p = new JPopupMenu(); JMenuItem ji = new JMenuItem("Marching Cubes from Images"); p.add(ji); ji.setEnabled(false); JMenuItem ji2 = new JMenuItem("Marching Cubes from GPU GLSL"); p.add(ji2); ji2.setEnabled(false); JMenuItem ji3 = new JMenuItem("Marching Cubes from Java (Groovy)"); p.add(ji3); ji3.setEnabled(true); ji3.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { doMarchingCubesFromJava(); } }); JMenuItem ji4 = new JMenuItem("Shader Object (GLSL DE)"); p.add(ji4); ji4.setEnabled(false); JMenuItem ji5 = new JMenuItem("Shader Object (GLSL Brute Force)"); p.add(ji5); ji5.setEnabled(false); p.show(inputButton, 0, 0); p.show(inputButton, 0, -p.getHeight()); } }); JButton modifyButton = new JButton("Modify"); buttonPanel.add(modifyButton); /* * Modify -> Apply Hemesh Modification * -> Delete * * Output -> to OBJ * -> to STL * -> Sunflow Render */ JButton outputButton = new JButton("Output"); buttonPanel.add(outputButton); return buttonPanel; } private void doMarchingCubesFromJava() { TextDialog td = new TextDialog(); td.setModal(true); td.setVisible(true); if (td.getCloseAction() == CloseAction.OK) { GroovyClassLoader gcl = new GroovyClassLoader(); Class clazz = gcl.parseClass(td.getCode()); SimpleMarchingCubes smc = null; try { smc = (SimpleMarchingCubes) clazz.newInstance(); gcl.close(); } catch (InstantiationException | IllegalAccessException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } if (smc == null) { return; } int res = td.getGridSize(); final SimpleMarchingCubes simpleMarchingCubes = smc; simpleMarchingCubes.initMarchingCubes(0, res, res, res, MainWindow.this, new Vector3(-1, -1, -1), new Vector3(1, 1, 1)); final ProgressMonitor pm = new ProgressMonitor(MainWindow.this, "Marching...", "Polygonizing", 0, res); pm.setMillisToDecideToPopup(1); Thread t = new Thread() { @Override public void run() { final Object3D o = simpleMarchingCubes.getObject3D(engine.getShaderState(), pm); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { project.addObject(o); } }); }; }; t.start(); } } @Override public void dispose() { openGlWindow.dispose(); super.dispose(); } private void setupMenus() { JMenuBar menuBar; JMenu menu; JMenuItem menuItem; menuBar = new JMenuBar(); menu = new JMenu("File"); menuBar.add(menu); menuItem = new JMenuItem("Exit", KeyEvent.VK_T); menu.add(menuItem); menuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { MainWindow.this.dispose(); } }); setJMenuBar(menuBar); } private static class TextAreaLogger extends Logger { private final JTextArea textArea = new JTextArea(); @Override protected void internalLog(Object obj) { String message = obj.toString() + "\n"; textArea.append(message); System.out.println(message); } public Component createComponent() { JScrollPane sp = new JScrollPane(textArea); sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); sp.setPreferredSize(new Dimension(50, 200)); return sp; } @Override protected void internalWarn(Object obj) { String message = "Warning: " + obj.toString() + "\n"; textArea.append(message); System.err.println(message); } } }